vapor-community / Imperial

Federated Authentication with OAuth providers
MIT License
153 stars 48 forks source link

Value required for key 'access_token'. #80

Open PanArtemG opened 3 years ago

PanArtemG commented 3 years ago

Hey! Can you please tell me what is the problem? I receive a response from FB and Google with the code but I cannot process it. The execution process is interrupted before reaching the last argument "completion" to process the incoming token and then get user data try routes.oAuth(from: Facebook.self, authenticate: "login-facebook", callback: facebookCallbackURL, scope: ["public_profile", "email"], completion: processFacebookLogin) Снимок экрана 2021-03-22 в 18 21 13

PanArtemG commented 3 years ago

If I add another route with the same address as facebookCallbackURL, the application swears that the route is being overwritten Warning: Overriding route output at: GET/oauth/facebook, but then a code comes to me and I can process it

`try routes.oAuth(from: Facebook.self, authenticate: "login-facebook", callback: facebookCallbackURL, scope: ["public_profile", "email"], completion: processFacebookLogin)

routes.get("oauth", "facebook", use: getCode)`

Code received Снимок экрана 2021-03-22 в 18 26 37

PanArtemG commented 3 years ago

SigIn with Google creates the same error

PanArtemG commented 3 years ago

Hi! The problem was my own, global JSON decoding was connected in the project `let encoder = JSONEncoder() encoder.keyEncodingStrategy = .convertToSnakeCase encoder.dateEncodingStrategy = .iso8601 ContentConfiguration.global.use(encoder: encoder, for: .json)

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .iso8601
ContentConfiguration.global.use(decoder: decoder, for: .json)`
0xTim commented 3 years ago

Reopening as Imperial should handle this better regardless of what global settings people have

froggomad commented 3 years ago

Interestingly, I'm getting a 200 back, but it comes with an error:

error=incorrect_client_credentials&error_description=The+client_id+and%2For+client_secret+passed+are+incorrect.&error_uri=https%3A%2F%2Fdocs.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-oauth-app-access-token-request-errors%2F%23incorrect-client-credentials

  • status : NIOHTTP1.HTTPResponseStatus.ok ▿ headers : Server: GitHub.com

Xcode Stack Trace

I'm probably using the wrong client secret or id judging by the URI I get back...

Edit: Yep, wrong client secret in my case

j4nos commented 1 year ago

I have almost the same issue.

Value of type 'String' required for key 'access_token'.

Something wrong here?

let githubMediaType = HTTPMediaType(type: "application", subType: "vnd.github+json")
ContentConfiguration.global.use(decoder: JSONDecoder(), for: githubMediaType)
ContentConfiguration.global.use(encoder: JSONEncoder(), for: githubMediaType)

Based on Oauth 2.0 spec access token is not needed in step 5, but it is fetched and returned in step 7.

oauth

danpalmer commented 1 year ago

Hi all, just wanted to say that I've unfortunately just lost an hour of debugging and stepping through a bunch of Imperial code to find this bug.

I think it's a clear bug that encoders/decoders customised by the Vapor installation are being used for interaction with upstream APIs that have an entirely different set of compatibility requirements.

It seems this affects at least Google and Facebook, and quite possibly others.

This will probably need an extension to each of the providers for them to define their own content decoder, and then use that instead of the global one that is used implicitly by https://github.com/vapor/vapor/blob/main/Sources/Vapor/Content/ContentContainer.swift#L128.

talmeme commented 10 months ago

I get the same error as in the issue subject with Keycloak. Making the following change worked for me:

--- a/Sources/ImperialKeycloak/KeycloakRouter.swift
+++ b/Sources/ImperialKeycloak/KeycloakRouter.swift
@@ -9,6 +9,7 @@ public class KeycloakRouter: FederatedServiceRouter {
     public let callbackURL: String
     public let accessTokenURL: String
     public let service: OAuthService = .keycloak
+    public let callbackHeaders = HTTPHeaders([("Content-Type", "application/x-www-form-urlencoded")])

     public required init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFut>
         self.tokens = try KeycloakAuth()