Hi,
I'm using a custom provider and during the callback redirection to my website, I get this error that breaks npm:
internal/validators.js:117
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received undefined
I tried to search around and can't seem to understand where it comes form as all the required parameters to build the provider were passed.
Am I missing something?
Thanks in advance
I'm facing the same issue, I'm currently using Laravel Passport as my custom providers too and received below errors on the callback:
data: '{
"error": "unsupported_grant_type",
"error_description":"The authorization grant type is not supported by the authorization server.",
"hint":"Check that all required parameters have been provided",
"message":"The authorization grant type is not supported by the authorization server."
}'
internal/validators.js:121
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received undefined
My oauth2 settings as bellow:
id : 'laravel_passport',
name : 'Laravel Passport',
type : 'oauth',
version : '2.0',
options : { grant_type: 'authorization_code' },
accessTokenUrl : 'http://localhost/laraval_passport/public/oauth/token',
requestTokenUrl : 'http://localhost/laraval_passport/public/oauth/authorize',
authorizationUrl : 'http://localhost/laraval_passport/public/oauth/authorize?response_type=code',
clientId : process.env.IDP_CLIENT_ID,
clientSecret : process.env.IDP_CLIENT_SECRET
thanks!
@mavichow can you change options to params and check if that works? I think that's the culprit.
@nunorbatista can you share your custom config?
@nunorbatista can you share your custom config?
Sure. It's an internal company app so I had to hide a few items.
{
id: [redacted],
name: [redacted],
type: 'oauth',
jwt: true,
version: '2.0',
params: { grant_type: 'authorization_code' },
accessTokenUrl: [redacted],
requestTokenUrl: [redacted],
authorizationUrl: [redacted],
clientId: process.env.client_id,
clientSecret: process.env.client_secret
}
The process only fails during the callback to my website.
Thanks for the help.
@nunorbatista try adding a scope: '' option too even if it's just an empty one. I'm not sure if that will fix it but I think that might work.
^ Those suggestions sound good! I didn't even think of those!
@nunorbatista
The ERR_INVALID_ARG_TYPE is from Babel, no idea what would be causing that, but scope suggestion sounds good.
BTW the jwt: true option should go on the options for the API route handler and not in the provider.
Unfortunately I have the exact same behavior. What I find strange is that it breaks the npm process completely. Below the full error for reference:
internal/validators.js:117
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received undefined
at validateString (internal/validators.js:117:11)
at Url.parse (url.js:159:3)
at Object.urlParse [as parse] (url.js:154:13)
at exports.OAuth2._request (C:\Users\batistan\Documents\Dev\react\[rea]-portal\node_modules\oauth\lib\oauth2.js:72:22)
at exports.OAuth2._get [as get] (C:\Users\batistan\Documents\Dev\react\[redacted]-portal\node_modules\next-auth\dist\server\lib\oauth\callback.js:1:4274)
at C:\Users\batistan\Documents\Dev\react\[redacted]-portal\node_modules\next-auth\dist\server\lib\oauth\callback.js:1:2122
at C:\Users\batistan\Documents\Dev\react\[redacted]-portal\node_modules\next-auth\dist\server\lib\oauth\callback.js:1:4040
at passBackControl (C:\Users\batistan\Documents\Dev\react\[redacted]-portal\node_modules\oauth\lib\oauth2.js:134:9)
at IncomingMessage.<anonymous> (C:\Users\batistan\Documents\Dev\react\[redacted]-portal\node_modules\oauth\lib\oauth2.js:157:7)
at IncomingMessage.emit (events.js:323:22)
at endReadableNT (_stream_readable.js:1204:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
code: 'ERR_INVALID_ARG_TYPE'
}
For the record, I just added Github as a provider and all is working fine.
btw @iaincollins - what is the right way to consume the Provider inside the Component? There's no documentation about that.
<Provider session={session}>
<Component {...pageProps} />
</Provider>
Thanks!
Hm okay, I thought it was OAuth missing some required options which were causing the error.
below the full error for reference:
Thanks, the full error is very helpful.
I suspect there is something wrong with your provider config, but I am not sure what. I would console.log() the output of the provider at run time. That error is happening because one of the values is empty. We can probably add some error handling to help point out which option is missing.
what is the right way to consume the Provider inside the Component?
Yes that's right, that is as show on the documentation page and in the example project.
All that's actually needed is:
import { Provider } from 'next-auth/client'
export default ({ Component, pageProps }) => {
return (
<Provider>
<Component {...pageProps} />
</Provider>
)
}
But, as the tip in the documentation mentions below the example, you can add session={session} (using session from session.pageProps) as an optimisation.
After some fiddling (and debug enabling) I managed to have this error in the console:
_GET_OAUTH_ACCESS_TOKEN_ERROR { statusCode: 400, data: 'Bad Request' } undefined undefined
GET_OAUTH2_ACCESS_TOKEN_ERROR { statusCode: 400, data: 'Bad Request' } undefined [redacted app id] [redacted code returned by the oauth app]
internal/validators.js:117
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
^
The first two lines seems to signal the problem, but I honestly don't know who is calling them.
I've also enabled logging at build time of the provider:
{
id: [redacted],
name: [redacted],
type: 'oauth',
scope: '',
version: '2.0',
params: [Object],
accessTokenUrl: '[redacted]/DM/APIIntegration/Token',
authorizationUrl: '[redacted]/DM/APIIntegration/AuthorizeFeatures?response_type=code',
clientId: [redacted],
clientSecret: [redacted]
}
Any help is appreciated.
Thanks
What does your callback URL look like? Could be something wrong with the encoding?
What does your callback URL look like? Could be something wrong with the encoding?
It lands here:
http://localhost:3000/api/auth/callback/[provider id]?code=[returned code]&state=[state]
Now that you talk about encoding, when I open the signin page on http://localhost:3000/api/auth/signin I get the following error on the console:
The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol.
Hi Lori & Iain, once again, thanks for the reply and truly appreciate for this!
I've still encounter errors:
http://localhost:3000/api/auth/callback/[provider id]?code=[returned code]&state=[state]
Same goes with mine, the callback url is similar with this
also i've tested the solutions by changing:
and here's my full error:
url.js:154
throw new ERR_INVALID_ARG_TYPE('url', 'string', url);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type undefined
at Url.parse (url.js:154:11)
at Object.urlParse [as parse] (url.js:148:13)
at exports.OAuth2._request (/Applications/MAMP/htdocs/nextauth/node_modules/oauth/lib/oauth2.js:72:22)
at exports.OAuth2._get [as get] (/Applications/MAMP/htdocs/nextauth/node_modules/next-auth/dist/server/lib/oauth/callback.js:1:4274)
at g.getOAuthAccessToken (/Applications/MAMP/htdocs/nextauth/node_modules/next-auth/dist/server/lib/oauth/callback.js:1:2122)
at _request (/Applications/MAMP/htdocs/nextauth/node_modules/next-auth/dist/server/lib/oauth/callback.js:1:4040)
at passBackControl (/Applications/MAMP/htdocs/nextauth/node_modules/oauth/lib/oauth2.js:134:9)
at IncomingMessage.<anonymous> (/Applications/MAMP/htdocs/nextauth/node_modules/oauth/lib/oauth2.js:157:7)
at IncomingMessage.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1145:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
To reproduce this error, please refer below config:
Nextauth Config:
providers: [{
id : 'laravel_passport',
name : 'Laravel Passport',
type : 'oauth',
version : '2.0',
params : { grant_type: 'authorization_code' },
scope : '',
accessTokenUrl : 'http://passport.01-px.com/oauth/token',
requestTokenUrl : 'http://passport.01-px.com/oauth/authorize',
authorizationUrl : 'http://passport.01-px.com/oauth/authorize?response_type=code',
clientId : 3,
clientSecret : '5ISyHTXUiTsUKkugpkJxiLMRLYGoYiwN1Nj1NK3Z'
}],
Laravel Passport Login access:
Laravel Passport client callback url has set to:
I'm using node:
@mavichow I am testing with your config but after logging in I get
ErrorException
Use of undefined constant JSON_INVALID_UTF8_SUBSTITUTE - assumed 'JSON_INVALID_UTF8_SUBSTITUTE'
http://passport.01-px.com/oauth/authorize?.
Also, I was getting the same error as both of you too but after updating the package I ran into the error above so I don't know if it works now.
Hmm this sounds like something is up with the Laravel Passport config, as I can see other people running into some of these errors using it with other libraries.
e.g. JSON_INVALID_UTF8_SUBSTITUTE is a PHP error.
I would ask the folks over at Laravel Passport if the config looks sane and for advice on common causes of that error.
I suspect the ERR_INVALID_ARG_TYPE arg is being throw from within next-auth (by a function it invokes) but I think it might be happening because either one of the URLs specified is invalid or returns an invalid response.
I was changing the Auth0 config to simplify it (just added a PR) and when I had a typo in one of the required URLs I was having the same error as referred to in this issue. So I guess it's probably just a wrong config? I'm not able to replicate it with custom providers unless there is a wrong URL.
After some testing, I still can't understand where the error comes from. It looks like some variable is undefined on the return, but I'm unable to understand where the process brakes.
I'll manually code the authentication system, I believe we can close this for now.
@ndom91 just added a logger; I'll keep this use case in mind when using it and will put in debug statements to log responses from OAuth clients in all flows, so it should be easier to see what is going on when debug: true (currently it only displays debug database adapter messages when set).
So, after a bit more testing:
[next-auth][error][OAUTH_GET_PROFILE_ERROR] [
{
statusCode: 400,
data: `{"error":"invalid_request","error_details":["IDX10709: 'jwtEncodedString' is not well formed: '6679DDE0FE4498064D7D3F7463E[truncated]'. The string needs to be in compact JSON format, which is of the form: '<Base64UrlEncodedHeader>.<Base64UrlEndcodedPayload>.<OPTIONAL, Base64UrlEncodedSignature>'."],"app_errors":[{"error_code":"Unexpected"}]}`
}
]
As an example, this is the token object returned by the application:
{
"access_token":"6E7BAAA9085AC5CD9F7D7FD[redacted]",
"refresh_token":"60B716A54E2618FB862E54E553[redacted]",
"token_type":"bearer",
"expires_in":86400
}
my provider config:
{
id: '[app id]',
name: '[app name]',
type: 'oauth',
version: '2.0',
scope: '',
params: { grant_type: 'authorization_code' },
accessTokenUrl: 'https://[url]/APIIntegration/Token',
authorizationUrl: 'https://[url]/APIIntegration/authorizefeatures?response_type=code',
profileUrl: '[url]/api/info/me',
profile: (profile) => {
return {
id: profile.Id,
name: profile.Name,
email: profile.Email,
login: profile.Login,
};
},
clientId: process.env.client_id,
clientSecret: process.env.client_secret,
},
is there something with the return that this library is not recognizing? I'm starting to believe the application I'm using to do the integration is not properly implementing oauth2
.
// [...nextauth].js
const options = {
site: process.env.SITE || 'http://localhost:3000',
providers: [{
id : 'laravel_passport',
name : 'Laravel Passport',
type : 'oauth',
version : '2.0',
params : { grant_type: 'authorization_code' },
scope : '',
accessTokenUrl : 'http://localhost/laravel_passport/public/oauth/token',
requestTokenUrl : 'http://localhost/laravel_passport/public/oauth/authorize',
authorizationUrl : 'http://localhost/laravel_passport/public/oauth/authorize?response_type=code',
profileUrl : 'http://localhost/laravel_passport/public/api/me',
profile: (profile) => {
console.log(profile)
return {
id : profile.id,
uid : profile.uid,
name : profile.name,
email : profile.email,
media : profile.media,
status : profile.status,
last_login_at : profile.last_login_at,
last_login_ip : profile.last_login_ip
};
},
clientId : 'my_client_id,
clientSecret : 'my_client_secret'
}],
}
I've tested, adding profileUrl, the callback don't have error & it redirected successfully back to index.js
But on index.js still asking me to signin & http://localhost:3000/api/auth/session return NULL
However on the my [...nextauth] profile function, i'm able to view my profile object in my terminal..
// index.js
import React from 'react'
import {
useSession,
signin,
signout
} from 'next-auth/client'
export default () => {
const [ session, loading ] = useSession()
return <p>
{!session && <>
Not signed in <br/>
<button onClick={signin}>Sign in</button>
</>}
{session && <>
Signed in as {session.user.email} <br/>
<button onClick={signout}>Sign out</button>
</>}
</p>
}
Am I missing something on configuring on cookie/session persisting on my nextuth config?
Tq all! truly appreciate it!
@nunorbatista Thanks for all the info, that is super helpful! The OAUTH_GET_PROFILE_ERROR doesn't halt execution, but is an indication that something is wrong.
I'm starting to believe the application I'm using to do the integration is not properly implementing oauth2
The OAuth spec is pain as it's very loosely defined and isn't strict about what payloads, behaviour and errors should be. It's better with OAuth2 but services still vary a lot while being technical compliant but incompatible. :-/
Most mainstream services are pretty straightforward, but even then providers like Apple throw a curveball by doing things differently. It sounds to be like something similar is happening in your case.
At first I thought maybe the data is encoded differently somehow. It would be interesting to see what is returned for the profile object if you add a console.log to the callback.
profile: (profile) => {
console.log(profile)
return {
id: profile.Id,
name: profile.Name,
email: profile.Email,
login: profile.Login,
};
},
… but then I looked again and the error IDX10709 seems to be Microsoft related error. It's like it's having a problem decoding a JWT. My best guess (based on where this error is triggered and that is seems to be an Microsoft error code?) is that the accessTokenUrl endpoint is expecting a JWT to be passed to it, but I might be wrong.
In NextAuth.js JWT profile decoding behaviour was reserved for the Apple provider (and that was hard coded), but I've just made it possible to use from any provider as there are Microsoft auth APIs that seem to use the same approach.
I don't think this will actually help in this case, but you might want to give it a go. To try it, update to the latest beta ([email protected]) and set the idToken option to true:
js
{
id: '[app id]',
name: '[app name]',
type: 'oauth',
version: '2.0',
scope: '',
idToken: true
/* etc... */
}
This will trigger a different routine for decoding user profiles; it will assume they are in JWT format from the provider. I would be interested to know if it works, and if it works, to know more about the provider (e.g. if it is an in house solution, what libraries it uses, etc ).
@mavichow Can you make your request for help a separate issue please? I don't think your problem is related. Thanks! You might want to try your provider with the example project to see if you get the same problem.
Hi @iaincollins,
First of all, thanks for the effort you put in the answer, is really appreciated.
I've updated to the beta.71 and enabled the getProfileFromToken: true. The result was an error that brakes execution in npm, below the output:
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var _client=_interopRequireDefault(require("./client")),_querystring=_interopRequireDefault(require("querystring")),_jwtDecode=_interopRequireDefault(require("jwt-decode")),_logger=_interopRequireDefault(require("../../../lib/logger"));function _interopRequireDefault(a){return a&&a.__esModule?a:{default:a}}function ownKeys(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);b&&(d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable})),c.push.apply(c,d)}return c}function _objectSpread(a){for(var b,c=1;c<arguments.length;c++)b=null==arguments[c]?{}:arguments[c],c%2?ownKeys(Object(b),!0).forEach(function(c){_defineProperty(a,c,b[c])}):Object.getOwnPropertyDescriptors?Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)):ownKeys(Object(b
Error: Missing JWT token
at _decodeToken ([redacted]\node_modules\next-auth\dist\server\lib\oauth\callback.js:1:4535)
at [redacted]\node_modules\next-auth\dist\server\lib\oauth\callback.js:1:2117
at [redacted]\node_modules\next-auth\dist\server\lib\oauth\callback.js:1:4227
at passBackControl ([redacted]\node_modules\oauth\lib\oauth2.js:134:9)
at IncomingMessage.<anonymous> ([redacted]\node_modules\oauth\lib\oauth2.js:157:7)
at IncomingMessage.emit (events.js:323:22)
at endReadableNT (_stream_readable.js:1204:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
The output of the console.log(profile) is undefined.
Regarding the provider, it's an acquired solution from an Australian vendor based on .NET. The source-code is not available so I don't know if they used a library or some kind of custom implementation.
I think the best is to abandon the idea of integrating this solution with next-auth and create a manual callback system that sets the token in a Cookie.
Let me know if you want to try something else to improve the library, but for me the issue can be closed.
Thanks for sticking with this and helping us go down the rabbit hole a bit to work out what was going on. I'm sorry it didn't work out in this case.
Probably the only thing we can practically do going forward is to improve the debug output to log responses (and indicate the URL that returned them) where we can in OAuth flows, which we can do now, thanks to work to add a logger by @ndom91
Note for posterity: The getProfileFromToken feature has been renamed idToken and documented here.
I have the same error. I think perhaps it comes from this in node_modules\next-auth\dist\server\lib\oauth\callback.js (can't find the same code in the repo) ☹:
function _get(provider, accessToken, callback) {
var url = provider.profileUrl;
var headers = provider.headers || {};
if (this._useAuthorizationHeaderForGET) {
headers.Authorization = this.buildAuthHeader(accessToken);
headers['Client-ID'] = provider.clientId;
accessToken = null;
}
this._request('GET', url, headers, null, accessToken, callback);
}
If I add a provider.profileUrl then this error does not occur, instead I get a different error (because I don't have a provider url for this custom provider atm). The documentation however says this property is optional. Can we fix this in the documentation or else make it optional in the code? Otherwise this issue is closed but the problem remains.
Thank you!
btw i got it working now with my custom provider (salesforce) once i added the profileUrl and the profile properties to my provider object. thanks so much for this! amazing! ✨
Most helpful comment
Thanks, the full error is very helpful.
I suspect there is something wrong with your provider config, but I am not sure what. I would console.log() the output of the provider at run time. That error is happening because one of the values is empty. We can probably add some error handling to help point out which option is missing.
Yes that's right, that is as show on the documentation page and in the example project.
All that's actually needed is:
But, as the tip in the documentation mentions below the example, you can add
session={session}(usingsessionfromsession.pageProps) as an optimisation.