I'm trying to exchange the authorization code I got in the first step of the documentation for access token. Where I'm stuck is how to send a request for the token that contains the code I've just got with the first request.
This is my code:
auth: {
redirect: {
login: '/',
callback: '/auth'
},
strategies: {
wrike: {
scheme: 'oauth2',
endpoints: {
authorization: 'https://login.wrike.com/oauth2/authorize/v4',
token: 'https://login.wrike.com/oauth2/token',
logout: '/'
},
token: {
property: 'access_token',
type: 'Bearer',
maxAge: 1800
},
responseType: 'code',
grantType: 'authorization_code',
accessType: 'offline',
clientId: XXXX,
client_secret: YYYY
}
}
}
I can't figure it out how I should set up the redirect URI, in the client or in the server side? How should I do the second request? (This below)
POST https://login.wrike.com/oauth2/token
//Parameters:
client_id=<client_id>
client_secret=<client_secret>
grant_type=authorization_code
code=<authorization_code>
I think Edward is right. It doesn't seem to work. You can either do the custom schema which is what I am going to do, or you can do what I currently have which is something like this (of course ignore all the console.log and stuff like that):
const urlParams = new URLSearchParams(window.location.search)
const code = urlParams.get('code')
const state = urlParams.get('state')
console.log('state', state)
console.log('stateStorage', window.localStorage.getItem(state))
if ((code && state) && state === window.localStorage.getItem('state')) {
this.$axios.post('http://publisher-local.co.uk:8080/oauth/token', {
grant_type: 'authorization_code',
client_id: 5,
redirect_uri: 'http://localhost:3000/auth',
code_verifier: window.localStorage.getItem('verifier'),
code
}).then(response => {
this.$auth.setUserToken(response.data.access_token)
this.$auth.fetchUser()
})
}
So basically after you are redirected back to your client after logging in on the server page just look for the details in the URL and make the request yourself.
Related
So, I was making a website and I needed Discord's OAuth2
However, this error keeps popping up for me:
data: { error: 'unsupported_grant_type' }
This here is my code:
function getToken(code) {
const data = new URLSearchParams({
client_id: 'ops',
client_secret: 'ops',
code: code,
grant_type: 'authorization_code',
redirect_uri: 'http://localhost:5500/callback',
scope: 'identify'
})
axios({
url: 'https://discord.com/api/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: data.toString()
}).then(response => {
return response.data
})
}
Just tried looking it up on the internet about. Since I was used to the old OAuth, I tried the old way. As I couldn't, I went after information in the Discord documentation. And I got this information.
However, without success.
Versions:
keycloak 12.0.2
nuxt: 2.14.6
nuxt/auth-next: 5.0.0-1622918202.e815752
Configs:
nuxt.config.js
auth: {
strategies: {
keycloak: {
scheme: '~/plugins/keycloak.js',
endpoints: {
authorization:'https://keycloak.bgzchina.com/auth/realms/bgzchina/protocol/openid-connect/auth',
token:'https://keycloak.bgzchina.com/auth/realms/bgzchina/protocol/openid-connect/token',
userInfo: "https://keycloak.bgzchina.com/auth/realms/bgzchina/protocol/openid-connect/token",
logout:'https://keycloak.bgzchina.com/auth/realms/bgzchina/protocol/openid-connect/logout',
},
responseType: 'id_token token',
clientId: 'centuari-portal-fe',
scope: ['openid'],
}
},
redirect: {
login: '/login',
logout: '/logout',
callback: '/callback',
home: '/',
}
},
router: {
middleware: ['auth']
},
due to a issue with current version nuxt/auth-next, I created a custom scheme by extending oauth2
/plugin/keycloak.js
import { Oauth2Scheme } from '~auth/runtime'
function encodeQuery(queryObject) {
return Object.entries(queryObject)
.filter(([_key, value]) => typeof value !== 'undefined')
.map(([key, value]) => encodeURIComponent(key) + (value != null ? '=' + encodeURIComponent(value) : ''))
.join('&')
}
export default class KeycloakScheme extends Oauth2Scheme {
logout() {
if (this.options.endpoints.logout) {
const opts = {
client_id: this.options.clientId,
post_logout_redirect_uri: this._logoutRedirectURI
}
const url = this.options.endpoints.logout + '?' + encodeQuery(opts)
window.location.replace(url)
}
return this.$auth.reset()
}
}
but when doing login, browser will block the token request due to CORS. keycloak server response for the preflight specify allowed method is POST, OPTIONS, but auth-next use GET to fetch token.
Is there any work around ?
You need to add/register the url into keycloak admin dashboard.
Go to keycloak admin dashboard
Menu Clients => select the client
On Settings tab, scroll down the page and find Web Origins. Add your frontend url (nuxt url) on it. Don't forget to add into Valid Redirect URIs too.
I am trying to integrate a NextJS application with Okta, using the Authorization code flow with PKCE. The flow is not complete because the token request is not being performed.
This is the configuration for the provider:
import NextAuth from 'next-auth';
const oktaBaseUrl = 'https://my-okta-domain.com/oauth2/[auth-server-id]';
const clientId = '[My Client Id]';
const authorizationUrl =
oktaBaseUrl +
'/v1/authorize?response_type=code&response_mode=query&state=false';
const accessTokenUrl = oktaBaseUrl + '/v1/token';
const profileUrl = oktaBaseUrl + '/v1/userinfo';
export default NextAuth({
providers: [
{
id: 'okta',
name: 'Okta',
type: 'oauth',
version: '2.0',
protection: 'pkce',
clientId,
clientSecret: '',
accessTokenUrl,
authorizationUrl,
profileUrl,
scope: 'services',
params: {
grant_type: 'authorization_code',
},
profile(profile) {
return {
id: profile.id as string,
name: profile.name,
email: profile.email
};
}
}
],
});
Thefirst stage seems to be perfromed correctly, but when okta returns the code, I only see a message in my application showing an 403 code. It seems it is trying to get the code without perform the request to the token endpoint
Message in console:
[next-auth][error][oauth_get_access_token_error]
https://next-auth.js.org/errors#oauth_get_access_token_error { statusCode: 403, data: '' } okta y64EzO0u9ZbwqFdjJWqapXggDmC1bWx2DGQaITCpta4
[next-auth][error][oauth_callback_error]
https://next-auth.js.org/errors#oauth_callback_error { statusCode: 403, data: '' }
Is there a configuration I am missing?
I have this Facebook strategy:
facebook: {
access_token_endpoint: 'http://***.**/api/v0/auth/social',
access_type: 'offline',
client_id: '*******',
grant_type: 'authorization_code',
redirect_uri: socialLoginUrl + '/account/aanmelden',
response_type: 'code',
token_key: 'jwt',
userinfo_endpoint: 'https://****.***.**/user/profile'
},
When I try to register with Facebook I get the following form in the request:
code: **
client_id: **
redirect_uri: **
response_type: **
grant_type: **
I want to supply some data to the back-end when I register:
"attributes":{
"code":"*****",
"vendor":"Facebook"
},
How do I add this to the form that's being sent to the access_token_endpoint ?
// updated question.
Calling the loginWith function:
#click="$auth.loginWith('facebook', { params: data })"
data object:
data () {
return {
data: {
type: 'user',
attributes: {
vendor: 'Facebook',
code: '**'
}
},
}
},
Request payload in the browser:
code=**&client_id=**&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Faccount%2Faanmelden&response_type=code&grant_type=authorization_code
Response from the back-end:
I expect the data object to be available in the payload, but I'm not sure if I'm doing this correctly.
From the official docs, it looks like you can do
this.$auth.loginWith('facebook', { params: { /* additional authentication parameters */ } })
.then(() => this.$toast.success('Logged In!'))
I never used it with Facebook but it's working great with local (using JWT).
The related part of the documentation: https://auth.nuxtjs.org/api/auth#loginwithstrategyname-args
I have following JS code to get the authentication code for the OAuth2 flow with Google:
gapi.client.init({
apiKey: apiKey,
clientId: clientId,
scope: scopes
});
//...
gapi.auth2.getAuthInstance().grantOfflineAccess({
scope: 'email profile'
})
.then(function(response) {
if (response && !response.error) {
// google authentication succeed, now post data to server.
$.ajax({
type: 'POST',
url: "my_url",
data: {
code: response.code
},
success: function(data) {
//...
},
error: function(er) {
console.log(er);
}
});
} else {
console.log('google authentication failed');
console.log(response)
}
});
The POST is made with the code to an Ruby on Rails app in which I use Signet gem to handle the authentication flow, I initialize it following way:
#client = Signet::OAuth2::Client.new(
:authorization_uri => 'https://accounts.google.com/o/oauth2/auth',
:token_credential_uri => 'https://www.googleapis.com/oauth2/v3/token',
:client_id => GCAL_CLIENT_KEY,
:client_secret => GCAL_CLIENT_SECRET,
:scope => 'email profile',
additional_parameters: {
"access_type" => "offline",
"include_granted_scopes" => "true"
}
)
and then try to get the access token:
#client.code = auth_code
#client.fetch_access_token!
But getting following exception:
#<Signet::AuthorizationError: Authorization failed. Server message:
{
"error": "unsupported_grant_type",
"error_description": "Invalid grant_type: "
}>
Tried also using HTTP/REST call to https://www.googleapis.com/oauth2/v4/token with request body as described here. But same response - invalid grant_type
You haven't set a redirect_uri in your Signet gem initialization, and it seems that Signet relies on that to set grant_type to authorization_code: https://github.com/google/signet/blob/621515ddeec1dfb6aef662cdfaca7ab30e90e5a1/lib/signet/oauth_2/client.rb#L834