【问题标题】:Google APi + Passport + React : Authentication flowGoogle APi + Passport + React:身份验证流程
【发布时间】: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)

我只需要在每次调用中发送令牌并在服务器端检查它。

谢谢

【问题讨论】:

    标签: node.js reactjs express passport.js google-oauth


    【解决方案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/

      【讨论】:

      【解决方案3】:

      您最有可能在标头中设置令牌,尝试将您的 axios 客户端更改为类似

      const api = axios.create({
        baseURL: 'http://localhost:3000/api',
        headers: {
          Authorization: `Bearer ${your_token_here}`
        }
      })
      

      我不能 100% 确定这是否是护照所期望的正确标题格式,但这是您需要做的一般想法。

      【讨论】:

      • 以及如何在服务器端验证该令牌? API 仍对公众开放调用
      猜你喜欢
      • 2017-09-09
      • 1970-01-01
      • 2020-12-31
      • 2018-02-12
      • 1970-01-01
      • 1970-01-01
      • 2012-11-24
      • 2020-07-05
      • 2014-12-24
      相关资源
      最近更新 更多