Oauth2 Google身份验证流-Next.JS/Express
我正在使用React/Next.Js前端,并试图用Google的Oauth2策略实现身份验证 我对这个过程感到非常困惑 目前在客户端上,我有一个Google登录组件,其中包含一个客户端ID,可以检索访问令牌Oauth2 Google身份验证流-Next.JS/Express,express,oauth-2.0,next.js,google-authentication,Express,Oauth 2.0,Next.js,Google Authentication,我正在使用React/Next.Js前端,并试图用Google的Oauth2策略实现身份验证 我对这个过程感到非常困惑 目前在客户端上,我有一个Google登录组件,其中包含一个客户端ID,可以检索访问令牌 <GoogleLogin clientId="myclientid" buttonText="Login" onSuccess={userLogin} onFailure={us
<GoogleLogin
clientId="myclientid"
buttonText="Login"
onSuccess={userLogin}
onFailure={userLogin}
cookiePolicy={'single_host_origin'}
/>
在后端,我使用passport,路径如下所示:
import express from 'express';
import passport from 'passport';
import Logger from '../logger/index';
const router = express.Router();
export function isAuthenticated(req:express.Request, res:express.Response, next : any) {
return req.isAuthenticated() ?
next() :
res.sendStatus(401);
}
router.get('/fail', (_req:express.Request, res:express.Response) => {
res.json({ loginFailed: true });
});
router.post('/google', passport.authenticate('google', { scope: ['profile']}), (_req:express.Request, _res:express.Response) => {
Logger.info("GET Request at Google Authentication endpoint received.");
});
router.get(
'/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
(_req:express.Request, res:express.Response) => {
res.redirect('/graphql');
}
);
export default router;
module.exports = function(passport : any, GoogleStrategy : any){
passport.use(new GoogleStrategy({
clientID: config.google.client_id,
clientSecret: config.google.client_secret,
callbackURL: config.google.redirect_url
},
function(accessToken : string, profile : Profile, refreshToken : string, cb : any) {
return cb(null, {
id: profile.googleId,
username: profile.email,
image: profile.imageUrl,
firstName: profile.givenName,
surname: profile.familyName,
accessToken: accessToken,
refreshToken: refreshToken
})
}
));
}
我的passport模块如下所示:
import express from 'express';
import passport from 'passport';
import Logger from '../logger/index';
const router = express.Router();
export function isAuthenticated(req:express.Request, res:express.Response, next : any) {
return req.isAuthenticated() ?
next() :
res.sendStatus(401);
}
router.get('/fail', (_req:express.Request, res:express.Response) => {
res.json({ loginFailed: true });
});
router.post('/google', passport.authenticate('google', { scope: ['profile']}), (_req:express.Request, _res:express.Response) => {
Logger.info("GET Request at Google Authentication endpoint received.");
});
router.get(
'/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
(_req:express.Request, res:express.Response) => {
res.redirect('/graphql');
}
);
export default router;
module.exports = function(passport : any, GoogleStrategy : any){
passport.use(new GoogleStrategy({
clientID: config.google.client_id,
clientSecret: config.google.client_secret,
callbackURL: config.google.redirect_url
},
function(accessToken : string, profile : Profile, refreshToken : string, cb : any) {
return cb(null, {
id: profile.googleId,
username: profile.email,
image: profile.imageUrl,
firstName: profile.givenName,
surname: profile.familyName,
accessToken: accessToken,
refreshToken: refreshToken
})
}
));
}
由于Next.js是服务器端渲染的,因此我无法使用save令牌。我知道我得用饼干。但是这是如何工作的呢?我无法从express后端重定向客户端浏览器
目前我只看到以下两个错误:
OPTIONS https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2localhost:3000%2Fdashboard&scope=profile&client_id=687602672235-l0uocpfchbjp34j1jjlv8tqv7jadb8og.apps.googleusercontent.com 405
Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fbackoffice.dev.myos.co%2Fdashboard&scope=profile&client_id=687602672235-l0uocpfchbjp34j1jjlv8tqv7jadb8og.apps.googleusercontent.com' (redirected from 'http://localhost:4000/auth/google') from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
首先,我认为google auth无法在本地主机上工作。
如果我在服务器端逻辑中理解正确,您可以轻松地将令牌保存为cookie,然后在客户端中读取它们 passport不确定,但您可以执行类似操作:
(我的应用程序正在使用此代码的实现) 前端:
<GoogleLogin
clientId="myclientid"
buttonText="Login"
onSuccess={userLogin}
onFailure={userLogin}
cookiePolicy={'single_host_origin'}
/>
然后在后端,您可以使用谷歌认证库
登录或注册。server.js
:
const {OAuth2Client} = require('google-auth-library');
const GOOGLEID = "mygoogleid.apps.googleusercontent.com"
const client = new OAuth2Client(GOOGLEID);
var cookieParser = require('cookie-parser')
async function verify(userToken) {
const ticket = await client.verifyIdToken({
idToken: userToken,
audience: "clientid.apps.googleusercontent.com", // Specify the CLIENT_ID of the app that accesses the backend
// Or, if multiple clients access the backend:
//[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]
});
const payload = ticket.getPayload();
const userid = payload['sub'];
return payload
// If request specified a G Suite domain:
//const domain = payload['hd'];
}
在server.js中
类似于以下内容的路由:
server.get('/google-login/:token',(req,res) => {
const userToken = req.params.token
var result = verify(userToken).then(function(result){
var userName = result.given_name
var userSurname = result.family_name
var userEmail = result.email
/*
Now user is authenticated i can send to the frontend
user info or user token o save the token to session
*/
}).catch(function(err){
// error handling
})
})
你可以用它来处理这件事。
为了测试localhost,您应该使用它向web公开您的localhost服务器,并在google platform中配置给定的url以澄清,在前端,我调用google服务,并返回一个包含访问令牌的对象。我从我的前端发布到后端,它通过调用GoogleAPI来验证这个访问令牌。成功后,我应该将某些内容发送回前端,这是一个cookie?这取决于您需要什么,您可以在后端设置cookie,或者您可以只发送回令牌(在验证后)并从前端设置cookie。