Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix OAuth2.0 based authentication examples problems using cookie #826

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion spotify-auth/firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
"rules": "database.rules.json"
},
"hosting": {
"public": "public"
"public": "public",
"rewrites": [
{
"source": "/redirect",
"function": "redirect"
},
{
"source": "/token",
"function": "token"
}
]
}
}
14 changes: 7 additions & 7 deletions spotify-auth/functions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,33 +41,33 @@ const Spotify = new SpotifyWebApi({
const OAUTH_SCOPES = ['user-read-email'];

/**
* Redirects the User to the Spotify authentication consent screen. Also the 'state' cookie is set for later state
* Redirects the User to the Spotify authentication consent screen. Also the '__session' cookie is set for later state
* verification.
*/
exports.redirect = functions.https.onRequest((req, res) => {
cookieParser()(req, res, () => {
const state = req.cookies.state || crypto.randomBytes(20).toString('hex');
const state = req.cookies.__session || crypto.randomBytes(20).toString('hex');
res.cookie('__session', state.toString(), {maxAge: 3600000, secure: true, httpOnly: true});
functions.logger.log('Setting verification state:', state);
res.cookie('state', state.toString(), {maxAge: 3600000, secure: true, httpOnly: true});
const authorizeURL = Spotify.createAuthorizeURL(OAUTH_SCOPES, state.toString());
res.redirect(authorizeURL);
});
});

/**
* Exchanges a given Spotify auth code passed in the 'code' URL query parameter for a Firebase auth token.
* The request also needs to specify a 'state' query parameter which will be checked against the 'state' cookie.
* The request also needs to specify a 'state' query parameter which will be checked against the '__session' cookie.
* The Firebase custom auth token is sent back in a JSONP callback function with function name defined by the
* 'callback' query parameter.
*/
exports.token = functions.https.onRequest((req, res) => {
try {
cookieParser()(req, res, () => {
functions.logger.log('Received verification state:', req.cookies.state);
functions.logger.log('Received verification state:', req.cookies.__session);
functions.logger.log('Received state:', req.query.state);
if (!req.cookies.state) {
if (!req.cookies.__session) {
throw new Error('State cookie not set or expired. Maybe you took too long to authorize. Please try again.');
} else if (req.cookies.state !== req.query.state) {
} else if (req.cookies.__session !== req.query.state) {
throw new Error('State validation failed');
}
functions.logger.log('Received auth code:', req.query.code);
Expand Down
4 changes: 2 additions & 2 deletions spotify-auth/public/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@
document.body.innerText = 'Error back from the Spotify auth page: ' + error;
} else if(!code) {
// Start the auth flow.
window.location.href = 'https://us-central1-' + getFirebaseProjectId() + '.cloudfunctions.net/redirect';
window.location.href = '/redirect';
} else {
// Use JSONP to load the 'token' Firebase Function to exchange the auth code against a Firebase custom token.
const script = document.createElement('script');
script.type = 'text/javascript';
// This is the URL to the HTTP triggered 'token' Firebase Function.
// See https://firebase.google.com/docs/functions.
var tokenFunctionURL = 'https://us-central1-' + getFirebaseProjectId() + '.cloudfunctions.net/token';
var tokenFunctionURL = '/token';
script.src = tokenFunctionURL +
'?code=' + encodeURIComponent(code) +
'&state=' + encodeURIComponent(state) +
Expand Down