1111
1212namespace chillerlan \OAuth \Providers ;
1313
14- use chillerlan \HTTP \Utils \QueryUtil ;
14+ use chillerlan \HTTP \Utils \{ MessageUtil , QueryUtil , UriUtil } ;
1515use chillerlan \OAuth \Core \{AccessToken , AuthenticatedUser , OAuthProvider , UserInfo };
16- use chillerlan \HTTP \Utils \UriUtil ;
1716use Psr \Http \Message \{RequestInterface , ResponseInterface , UriInterface };
18- use function explode , intval , preg_replace ;
17+ use function explode , intval , str_replace ;
1918
2019/**
2120 * Steam OpenID
2221 *
2322 * @see https://steamcommunity.com/dev
2423 * @see https://partner.steamgames.com/doc/webapi_overview
24+ * @see https://partner.steamgames.com/doc/features/auth
2525 * @see https://steamwebapi.azurewebsites.net/
2626 */
2727class Steam extends OAuthProvider implements UserInfo{
@@ -54,9 +54,22 @@ public function getAuthorizationURL(array|null $params = null, array|null $scope
5454 }
5555
5656 /**
57- *
57+ * Obtains an "authentication token" (the steamID64)
58+ */
59+ public function getAccessToken (array $ urlQuery ):AccessToken {
60+ $ body = $ this ->getAccessTokenRequestBodyParams ($ urlQuery );
61+ $ response = $ this ->sendAccessTokenRequest ($ this ->accessTokenURL , $ body );
62+ $ token = $ this ->parseTokenResponse ($ response , $ urlQuery ['openid_claimed_id ' ]);
63+
64+ $ this ->storage ->storeAccessToken ($ token , $ this ->name );
65+
66+ return $ token ;
67+ }
68+
69+ /**
70+ * prepares the request body parameters for the access token request
5871 */
59- public function getAccessToken (array $ received ):AccessToken {
72+ protected function getAccessTokenRequestBodyParams (array $ received ):array {
6073
6174 $ body = [
6275 'openid.mode ' => 'check_authentication ' ,
@@ -68,33 +81,27 @@ public function getAccessToken(array $received):AccessToken{
6881 $ body ['openid. ' .$ item ] = $ received ['openid_ ' .$ item ];
6982 }
7083
84+ return $ body ;
85+ }
86+
87+ /**
88+ * sends a request to the access token endpoint $url with the given $params as URL query
89+ */
90+ protected function sendAccessTokenRequest (string $ url , array $ body ):ResponseInterface {
91+
7192 $ request = $ this ->requestFactory
72- ->createRequest ('POST ' , $ this -> accessTokenURL )
93+ ->createRequest ('POST ' , $ url )
7394 ->withHeader ('Content-Type ' , 'application/x-www-form-urlencoded ' )
7495 ->withBody ($ this ->streamFactory ->createStream (QueryUtil::build ($ body )));
7596
76- $ token = $ this ->parseTokenResponse ($ this ->http ->sendRequest ($ request ));
77- $ id = preg_replace ('/[^\d]/ ' , '' , $ received ['openid_claimed_id ' ]);
78-
79- // as this method is intended for one-time authentication only we'll not receive a token.
80- // instead we're gonna save the verified steam user id as token as it is required
81- // for several "authenticated" endpoints.
82- $ token ->accessToken = $ id ;
83- $ token ->extraParams = [
84- 'claimed_id ' => $ received ['openid_claimed_id ' ],
85- 'id_int ' => intval ($ id ),
86- ];
87-
88- $ this ->storage ->storeAccessToken ($ token , $ this ->name );
89-
90- return $ token ;
97+ return $ this ->http ->sendRequest ($ request );
9198 }
9299
93100 /**
94101 * @throws \chillerlan\OAuth\Providers\ProviderException
95102 */
96- protected function parseTokenResponse (ResponseInterface $ response ):AccessToken {
97- $ data = explode ("\x0a" , ( string ) $ response-> getBody ( ));
103+ protected function parseTokenResponse (ResponseInterface $ response, string $ claimed_id ):AccessToken {
104+ $ data = explode ("\x0a" , MessageUtil:: getContents ( $ response ));
98105
99106 if (!isset ($ data [1 ]) || !str_starts_with ($ data [1 ], 'is_valid ' )){
100107 throw new ProviderException ('unable to parse token response ' );
@@ -104,17 +111,24 @@ protected function parseTokenResponse(ResponseInterface $response):AccessToken{
104111 throw new ProviderException ('invalid id ' );
105112 }
106113
107- // the response is only validation, so we'll just return an empty token and add the id in the next step
108114 $ token = $ this ->createAccessToken ();
115+ $ id = str_replace ('https://steamcommunity.com/openid/id/ ' , '' , $ claimed_id );
109116
110- $ token ->accessToken = 'SteamID ' ;
117+ // as this method is intended for one-time authentication only we'll not receive a token.
118+ // instead we're gonna save the verified steam user id as token as it is required
119+ // for several "authenticated" endpoints.
120+ $ token ->accessToken = $ id ;
111121 $ token ->expires = AccessToken::NEVER_EXPIRES ;
122+ $ token ->extraParams = [
123+ 'claimed_id ' => $ claimed_id ,
124+ 'id_int ' => intval ($ id ),
125+ ];
112126
113127 return $ token ;
114128 }
115129
116130 /**
117- *
131+ * @inheritDoc
118132 */
119133 public function getRequestAuthorization (RequestInterface $ request , AccessToken |null $ token = null ):RequestInterface {
120134 $ uri = UriUtil::withQueryValue ($ request ->getUri (), 'key ' , $ this ->options ->secret );
0 commit comments