代码之家  ›  专栏  ›  技术社区  ›  jeanpaul62

Auth0:在Auth0注册后在本地数据库中创建用户

  •  5
  • jeanpaul62  · 技术社区  · 7 年前

    我正在使用Auth0托管所有用户数据。我也有自己的后台,我希望有一个 Users userId 认证 user_id . 我在注册时的两个流程之间犹豫:

    注册流程1:

    1. 前端显示锁,用户注册。
    2. 在Auth0重定向回前端后,前端具有Auth0 用户id
    3. 前端在上调用后端 POST /users (公共终结点)创建新用户 用户id .
    4. 在对后端资源服务器的每个经过身份验证的请求中,JWT包含auth0 用户id ,所以数据库在 还有我的 用户ID .

    1. 前端显示锁,用户注册。
    2. 帖子/用户 用户ID 并将其发送回Auth0。
    3. 用户ID 进入Auth0 user_metadata .
    4. 用户元数据 将包含在JWT中,因此所有到我的后端获取资源的调用都将包括db 用户ID

    我觉得2号比较结实。还有其他报名流程吗?一些auth0客户是否使用与my#2类似的流?我在他们的文件里找不到什么。

    1 回复  |  直到 7 年前
        1
  •  13
  •   iqbal125    7 年前

    这是我的第一篇文章,如果我犯了新的错误,请原谅。

    我发现注册流程1工作得很好。您没有指定您使用的技术,但这里有一个链接到我的github,在这里我有一个功能完善的博客,使用带有React、redux和Express后端的注册流1。

    https://github.com/iqbal125/react-redux-fullstack-blog

    我将用这些框架来演示,希望您可以调整您正在使用的任何框架的代码。

    我的注册流程如下:

    1. 用户被重定向到回调页。
    2. 然后从回调页重定向到“auth check”页。我在auth check页面中有一个嵌套的api调用,这两个调用都从auth0获取用户数据,然后立即调用api端点将用户数据保存到db。
    3. 然后将用户数据保存到redux全局状态,并可用于在用户配置文件页上显示数据。
    4. 验证检查然后重定向回主页。



    一。前端显示锁定用户注册

      login() {
        this.auth0.authorize();
       }
    


    我的回调页非常简单,我把它用作函数组件。

      <div>
        <h2>Callback</h2>
      </div>
    


    三。然后从回调页重定向到“auth check”页

    我是通过auth.js util组件中的handleAuthentication()函数来实现的。代码是从auth0示例中稍微修改的。

      handleAuthentication() {
        this.auth0.parseHash((err, authResult) => {
          if (authResult && authResult.accessToken && authResult.idToken) {
            this.setSession(authResult);
            this.getProfile();
            setTimeout( function() { history.replace('/authcheck') }, 2000);
          } else if (err) {
            history.replace('/');
            console.log(err);
            alert(`Error: ${err.error}. Check the console for further details.`);
          }
        });
       }
    

       getProfile() {
        let accessToken = this.getAccessToken();
        if(accessToken) {
          this.auth0.client.userInfo(accessToken, (err, profile) => {
            if (profile) {
              this.userProfile = { profile };
             }
           });
         }
        }
    

    以及getAccessToken()函数

      getAccessToken() {
        if (localStorage.getItem('access_token')) {
          const accessToken = localStorage.getItem('access_token')
          return accessToken
        }
        else {
          console.log("No accessToken")
          return null
        }
       }
    

    auth.js util组件中的这两个函数将允许我们从auth0获取信息并将其保存到类中声明的空对象中。

      userProfile = {}
    

    转到auth-check.js容器。我首先在构造函数中声明函数,然后是函数本身。然后我调用componentDidMount()生命周期方法,该方法在组件呈现时自动运行。

      constructor() {
        super()
        this.send_profile_to_db = this.send_profile_to_db.bind(this)
      }
    
       send_profile_to_db (profile) {
        const data = profile
        axios.post('api/post/userprofiletodb', data)
        .then(() => axios.get('api/get/userprofilefromdb', {params: {email: profile.profile.email}} )
          .then(res => this.props.db_profile_success(res.data))
          .then(history.replace('/')))
       }
    

    componentDidMount() {
        if(this.props.auth.isAuthenticated()) {
          this.props.login_success()
          this.props.db_profile_success(this.props.auth.userProfile)
          this.send_profile_to_db(this.props.auth.userProfile)
        } else {
          this.props.login_failure()
          this.props.profile_failure()
          this.props.db_profile_failure()
          history.replace('/')
        }
      }
    
       render() {
        return (
            <div>
           </div>
        )
      }
    }
    

    我认为这里的代码是你所问问题的核心。

    我将从 将配置文件发送到数据库() 功能。

    这里我使用axios来发出请求。我开始对我的express服务器进行后端api调用(我将在下一步中解释),并使用axios将用户配置文件作为数据对象参数传递给Im。您可能想知道实际的用户配置文件数据来自何处。

    在routes.js根组件中,我导入并初始化了Auth的一个新实例

    export const auth = new Auth();
    

    然后将其作为道具传递给AuthCheck组件。

    <Route path="/authcheck" render={(props) => <AuthCheck auth={auth} {...props} />} />
    

    使用嵌套的“.then()”函数将数据发布到数据库Im后,该函数调用axios get请求,并将用户电子邮件作为从数据库中查找配置文件的参数。数据库配置文件包含有关用户帖子和用户评论的数据。这将有助于在应用程序中显示数据。然后使用另一个“.Then()”语句和Redux Thunk异步地将用户配置文件数据保存到全局Redux状态。

    总之,这个authcheck组件做了4件事:
    一。将从auth0获取的用户配置文件数据保存到自己的数据库。
    2。然后在保存数据之后,立即从我们的数据库中检索相同的配置文件。

    四。将数据库用户配置文件数据保存到全局redux状态,以便在其他组件中使用。



    四。api调用检查用户是否已经在sql db中,然后保存用户数据,否则不执行任何操作。

    这是我的服务器设置。用户对数据库的“post”和“get”请求。

    router.post('/api/post/userprofiletodb', (req, res, next) => {
      const values = [req.body.profile.nickname, req.body.profile.email, req.body.profile.email_verified]
      pool.query('INSERT INTO users(username, email, date_created, email_verified) VALUES($1, $2, NOW(), $3) ON CONFLICT DO NOTHING', values, (q_err, q_res) => {
        if (q_err) return next(q_err);
        console.log(q_res)
        res.json(q_res.rows);
      });
    });
    
    /* Retrieve user profile from db */
    router.get('/api/get/userprofilefromdb', (req, res, next) => {
      // const email = [ "%" + req.query.email + "%"]
      const email = String(req.query.email)
      pool.query("SELECT * FROM users WHERE email = $1", [ email ], (q_err, q_res) => {
        res.json(q_res.rows)
      });
    });
    

    路由器对象是express.router()。我正在使用psql。

    请记住添加“ON CONFLICT DO NOTHING”,否则将保存同一用户的多个版本。

    我认为auth0还提供了几个数据点,但我最终没有使用它们。

    CREATE TABLE users (
      uid SERIAL PRIMARY KEY,
      username VARCHAR(255) UNIQUE,
      email VARCHAR(255),
      email_verified BOOLEAN,
      date_created DATE,
      last_login DATE
    );
    



    5个。然后将用户数据保存到redux全局状态,并可用于在用户配置文件页上显示数据。

    最后我在第三步解释了这一点。



    参见步骤3



    7号。验证检查然后重定向回主页。

    再一次看第三步,哈哈。


    如果你感兴趣或者我漏掉了什么,一定要查看我的repo,就像我说的,这是一个功能齐全的博客。

    推荐文章