-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathCredentials.php
125 lines (108 loc) · 3.59 KB
/
Credentials.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?php
/**
* Created by PhpStorm.
* User: lkaybob
* Date: 19/03/2018
* Time: 21:37
*/
namespace phpFCMv1;
use \Firebase\JWT\JWT;
use \GuzzleHttp;
class Credentials {
const SCOPE = 'https://www.googleapis.com/auth/firebase.messaging';
const TOKEN_URL = 'https://www.googleapis.com/oauth2/v4/token';
const EXPIRE = 3600;
const ALG = 'RS256';
const CONTENT_TYPE = 'form_params';
const GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:jwt-bearer';
const METHOD = 'POST';
const HTTP_ERRORS_OPTION = 'http_errors';
private $keyFilePath;
private $DATA_TYPE;
// Added to save access_token and use it until expire
private $access_token = '';
private $expire = 0;
/**
* Credentials constructor. Checks whether given path is a valid file.
* @param string $keyFile
* @throws \InvalidArgumentException when file is not found
*/
public function __construct($keyFile = 'service_account.json') {
if (is_file($keyFile)) {
$this -> setKeyFilePath($keyFile);
} else {
throw new \InvalidArgumentException('Key file could not be found', 1);
}
}
/**
* @return string Access token for a project
*/
public function getAccessToken() {
$requestBody = array(
'grant_type' => self::GRANT_TYPE,
'assertion' => $this -> getTokenPayload()
);
if ( strlen( $this->access_token ) == 0 || ( $this->expire <= time() ) ) {
$result = $this -> getToken($requestBody);
if (isset($result['error'])) {
$this->access_token = '';
$this->expire = 0;
throw new \RuntimeException($result['error_description']);
} else {
$this->access_token = $result['access_token'];
$this->expire = time() + $result['expires_in'];
}
}
return $this->access_token;
}
/**
* @return string Signed payload (with private key using algorithm)
*/
private function getTokenPayload() {
$keyBody = json_decode(
file_get_contents($this -> getKeyFilePath()), true
);
$now = (new \DateTime()) -> format('U');
$iat = intval($now);
$payload = array(
'iss' => $keyBody['client_email'],
'scope' => self::SCOPE,
'aud' => self::TOKEN_URL,
'iat' => $iat,
'exp' => $iat + self::EXPIRE,
'sub' => null
);
$signedJWT = JWT ::encode($payload, $keyBody['private_key'], self::ALG);
return $signedJWT;
}
/**
* @param $requestBody array Payload with assertion data (which is signed)
* @return array Associative array of cURL result
* @throws GuzzleHttp\Exception\GuzzleException
* This exception is intentional
*/
private function getToken($requestBody) {
$client = new GuzzleHttp\Client();
$response = $client -> request(self::METHOD, self::TOKEN_URL,
array(self::CONTENT_TYPE => $requestBody, self::HTTP_ERRORS_OPTION => false));
return json_decode($response->getBody(), true);
}
public function getProjectID() {
$keyBody = json_decode(
file_get_contents($this -> getKeyFilePath()), true
);
return $keyBody['project_id'];
}
/**
* @return mixed
*/
public function getKeyFilePath() {
return $this -> keyFilePath;
}
/**
* @param mixed $keyFilePath
*/
public function setKeyFilePath($keyFilePath) {
$this -> keyFilePath = $keyFilePath;
}
}