首页 > 解决方案 > 如何将护照 js 策略与社交提供者(Facebook、Twitter 等)与 React 相结合

问题描述

我知道这里有人问过这个问题,如何同时使用 passportjs 和 reactjs?但它似乎没有回答这个问题,我试图对此进行研究,但我似乎找不到任何东西/

现在这就是我理解事物并实施它的方式。

在前端,我将 tokenId 发送到服务器,服务器将其发送到社交提供商(FB、谷歌等),它会验证我的令牌。如果正确,我会生成一个 JWT 令牌并将其发送回前端并将令牌存储为 cookie 并将用户 obj 存储为本地存储。

客户端,我有一个 facebook 登录组件。我正在获取令牌并使用 axios 将其发送到服务器。

客户端

import React from 'react';
import axios from 'axios'
import FacebookLogin from 'react-facebook-login/dist/facebook-login-render-props';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { library } from '@fortawesome/fontawesome-svg-core';
import { fab } from '@fortawesome/free-brands-svg-icons';

const FacebookLoginComponent = ({ informParent }) => {
        const responseFacebook = async (response) => {
            if (response) {
                const { accessToken, id } = await response
                return await axios
                    .post(`${process.env.REACT_APP_API}/facebook-login`, {
                        accessToken,
                        userId: id
                    })
                    .then(response => {
                        const data = response.data
                        console.log(data) // Contains user obj and jwt token from backend
                    })
                    .catch(error => {
                        console.log(error)
                    })
            }
            return false
        }
    
        return (<FacebookLogin
            appId={process.env.REACT_APP_FACEBOOK_ID}
            autoLoad={false}
            callback={responseFacebook}
            render={renderProps => (
                <button className="btn btn-primary w-100" onClick={renderProps.onClick} disabled={renderProps.disabled} >
                    <FontAwesomeIcon icon={['fab', 'facebook']} />  Login with Facebook
                </button>
            )}
        />)
    }

服务器端从这里,我基本上是从前端获取访问令牌。然后我会将访问令牌和用户 ID 发送到 facebook 的 api url 并获取名称和电子邮件。然后,如果找到电子邮件,我将使用电子邮件创建用户或登录用户。

router.post('/facebook-login', FacebookLoginController)

const FacebookLoginController = async (req, res) => {
    const { accessToken, userId } = req.body
    const url = `https://graph.facebook.com/v2.11/${userId}/?fields=id,name,email&access_token=${accessToken}`
    fetch(url)
        .then(res => res.json())
        .then(json => {
            const { id, name, email } = json
            // console.log(json)
            if (email) {
                try {
                    return User.findOne({ email }, async (err, user) => {
                        if (err) {
                            return await res.status(500).json({
                                status: 'Failed',
                                msg: 'Something went wrong',
                                err
                            })
                        }
                        //If no user, create a new user
                        if (!user) {
                            let newUser = await new User({
                                username: name,
                                email,
                                password: email + process.env.JWT_SECRET,
                            })
                            return await newUser.save(async (err, data) => {
                                if (err) {
                                    return await res.status(500).json({
                                        error: err
                                    })
                                }
                                const { _id, username, email, role } = data
                                const token = jwt.sign(
                                    { _id },
                                    process.env.JWT_SECRET,
                                    { expiresIn: "7d" }
                                );
                                return await res.status(200).json({
                                    status: 'Success',
                                    message: 'User saved Successfully',
                                    token,
                                    user: {
                                        _id, username, email, role
                                    }
                                })
                            })
                        } else {
                            //User exists , login
                            const { _id, username, email, role } = user
                            const token = jwt.sign(
                                { _id },
                                process.env.JWT_SECRET,
                                { expiresIn: "7d" }
                            );
                            return await res.status(200).json({
                                status: 'Success',
                                message: 'User login Successfully',
                                user: {
                                    _id, username, email, role
                                },
                                token
                            })
                        }
                    })
                } catch (error) {
                    return res.status(500).json(error)
                }
            }
        })
        .catch(error => {
            return res.status(500).json(error)
        })
}

我阅读了护照文件,但似乎无法将其拼凑起来。我了解他们的护照序列化用户 ID 并将其存储在会话中。所以我们可以使用 req.user 来获取用户。

所以我的问题是当 react 在前端时,passport js 如何与社交提供者一起做事?

我看过的很多教程,他们似乎都在使用快速会话。

希望有人可以向我解释,因为我对护照如何进行身份验证有点困惑。

标签: node.jsreactjsfacebookpassport.js

解决方案


推荐阅读