-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(provider): re-add state, expand protection provider options (#1184)
* refactor: move OAuthCallbackError to errors file * refactor: improve pkce handling * feat(provider): re-introduce state to provider options * docs(provider): mention protection options "state" and "none" * docs(provider): document state property deprecation * fix: only add code_verifier param if protection is pkce * docs: explain state deprecation better * chore: unify string
- Loading branch information
1 parent
393bd4a
commit f4d9e54
Showing
10 changed files
with
148 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { createHash } from 'crypto' | ||
import logger from '../../../lib/logger' | ||
import { OAuthCallbackError } from '../../../lib/errors' | ||
|
||
/** | ||
* For OAuth 2.0 flows, if the provider supports state, | ||
* check if state matches the one sent on signin | ||
* (a hash of the NextAuth.js CSRF token). | ||
*/ | ||
export async function handleCallback (req, res) { | ||
const { csrfToken, provider, baseUrl, basePath } = req.options | ||
try { | ||
if (provider.protection !== 'state') { // Provider does not support state, nothing to do. | ||
return | ||
} | ||
|
||
const { state } = req.query | ||
const expectedState = createHash('sha256').update(csrfToken).digest('hex') | ||
|
||
logger.debug( | ||
'OAUTH_CALLBACK_PROTECTION', | ||
'Comparing received and expected state', | ||
{ state, expectedState } | ||
) | ||
if (state !== expectedState) { | ||
throw new OAuthCallbackError('Invalid state returned from OAuth provider') | ||
} | ||
} catch (error) { | ||
logger.error('STATE_ERROR', error) | ||
return res.redirect(`${baseUrl}${basePath}/error?error=OAuthCallback`) | ||
} | ||
} | ||
|
||
/** Adds CSRF token to the authorizationParams. */ | ||
export async function handleSignin (req, res) { | ||
const { provider, baseUrl, basePath, csrfToken } = req.options | ||
try { | ||
if (provider.protection !== 'state') { // Provider does not support state, nothing to do. | ||
return | ||
} | ||
|
||
if ('state' in provider) { | ||
logger.warn( | ||
'STATE_OPTION_DEPRECATION', | ||
'The `state` provider option is being replaced with `protection`. See the docs.' | ||
) | ||
} | ||
|
||
// A hash of the NextAuth.js CSRF token is used as the state | ||
const state = createHash('sha256').update(csrfToken).digest('hex') | ||
|
||
provider.authorizationParams = { ...provider.authorizationParams, state } | ||
logger.debug( | ||
'OAUTH_CALLBACK_PROTECTION', | ||
'Added state to authorization params', | ||
{ state } | ||
) | ||
} catch (error) { | ||
logger.error('SIGNIN_OAUTH_ERROR', error) | ||
return res.redirect(`${baseUrl}${basePath}/error?error=OAuthSignin`) | ||
} | ||
} | ||
|
||
export default { handleSignin, handleCallback } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters