Google APi + Passport + React:身份验证流程
Posted
技术标签:
【中文标题】Google APi + Passport + React:身份验证流程【英文标题】:Google APi + Passport + React : Authentication flow 【发布时间】:2020-06-02 14:58:16 【问题描述】:我正在使用护照通过 Google API 进行身份验证,我正在通过 URL 向客户端(React 应用程序)发送一个令牌,客户端将其保存在 localStorage 中。
我想使用该令牌:对于每个 API 调用(get、post、put),我都想将该令牌发送到服务器,但我不知道如何在服务器端验证该令牌。
护照攻略:
app.use(passport.initialize()); // Used to initialize passport
app.use(passport.session()); // Used to persist login sessions
passport.use(new GoogleStrategy(
clientID: 'IDxxxxx',
clientSecret: 'SecreXXX',
callbackURL: 'http://localhost:3000/callback'
,
(accessToken, refreshToken, profile, done) =>
// Directory API here
var userData =
name: profile.displayName,
token: accessToken
;
done(null, userData);
身份验证:
app.get('/auth/google', passport.authenticate('google',
scope: ['profile'] // Used to specify the required data
));
// The middleware receives the data from Google and runs the function on Strategy config
app.get('/callback', passport.authenticate('google'), (req, res) =>
var token = req.user.token;
res.redirect("http://localhost:8000?token=" + token);
);
express 中的 API(包含 CRUD 方法):
app.use('/api', movieRouter)
在反应方面:获取令牌
componentWillMount()
var query = queryString.parse(this.props.location.search);
if (query.token)
window.localStorage.setItem("jwt", query.token);
// appel a directory api (avec token) puis sauvergarder dans redux puis redirection vers liste demandes
this.props.history.push("/");
做 API 调用:
import axios from 'axios'
const api = axios.create(
baseURL: 'http://localhost:3000/api',
)
export const insertMovie = payload => api.post(`/movie`, payload)
我只需要在每次调用中发送令牌并在服务器端检查它。
谢谢
【问题讨论】:
【参考方案1】:对于您要验证令牌的每个 API,您可以在执行以下操作之前传递一个验证令牌函数(我称之为“isCorrectToken”):
router.get("/api", isCorrectToken, (req, res) =>
// your api content )
然后,这就是我们的 isCorrectToken 函数:
const isCorrectToken = (req, res, next) =>
const token = req.headers.authorization;
if(token)
const onlyToken = token.slice(7, token.length);
jwt.verify(onlyToken, accessToken, (err, decode) =>
if(err) return res.status(401).send( msg: 'Invalid Token' );
req.user = decode;
next();
return;
);
else return res.status(401).send( msg: 'Token is not supplied');
数字 7 是“Bearer”的长度(来自 Bill Metcalf 的上述回答)。
【讨论】:
【参考方案2】:如 Bill Metcalf 所述,如果客户端在标头、会话或 cookie 中正确设置了令牌,则 express 能够通过将 passport.authenticate 中间件函数添加到路由来对路由/端点进行身份验证,如下所示
app.use('/api', passport.authenticate('google', failureRedirect:'/login'), movieRouter)
更多信息请参考http://www.passportjs.org/docs/google/
【讨论】:
从源“localhost:8000”访问“accounts.google.com/o/oauth2/v2/…”处的 XMLHttpRequest(从“localhost:3000/api/movie/5e46bc5b8467a51ae4b90f3a'”重定向)已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查: 请求的资源上不存在“Access-Control-Allow-Origin”标头。【参考方案3】:您最有可能在标头中设置令牌,尝试将您的 axios 客户端更改为类似
const api = axios.create(
baseURL: 'http://localhost:3000/api',
headers:
Authorization: `Bearer $your_token_here`
)
我不能 100% 确定这是否是护照所期望的正确标题格式,但这是您需要做的一般想法。
【讨论】:
以及如何在服务器端验证该令牌? API 仍对公众开放调用以上是关于Google APi + Passport + React:身份验证流程的主要内容,如果未能解决你的问题,请参考以下文章
使用 passport.js 将本地策略连接到另一个(Facebook、Twitter、Google 等)
如何使用 JWT 和 Passport 正确使用 nodeJs API 的身份验证?
Google oauth20 的 Passport,未使用中间件,passport.initialize()