当前位置: 首页 > 知识库问答 >
问题:

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

麻学博
2023-03-14

我使用Auth0来托管我所有的用户数据。我也有自己的后端,我希望在其中有一个用户表,它将把我数据库生成的userId映射到Auth0的user_id。我在注册时在两个流程之间犹豫:

  1. 前端显示锁定,用户注册。
  2. Auth0 重定向回前端后,前端具有 Auth0 user_id
  3. 前端在 POST /users(公共终结点)上调用后端,以使用 user_id 创建新用户。
  4. 在对我的后端资源服务器的每个经过身份验证的请求中,JWT 都包含 auth0 user_id,因此数据库会在user_id和我的 userID 之间进行查找。
  1. 前端显示锁定,用户注册。
  2. 在 Auth0 上配置一个注册后挂钩,在我的后端调用 POST /users。此调用将生成我的数据库的 userId 并将其发送回 Auth0。
  3. 将此用户 ID 放入 Auth0 的user_metadata中。
  4. user_metadata将包含在 JWT 中,因此对我的后端获取资源的所有调用都将包含数据库的 userId(无需额外查找)。

我觉得2更扎实。还有其他注册流程吗?某些auth0客户是否使用与我的#2类似的流程?我在他们的文档中找不到太多。

共有2个答案

曾光誉
2023-03-14

Flow 1 会在每次成功登录时对数据库执行“插入或忽略”命令,在大规模情况下,这不是一个好的做法。事实上,这也是 DoS 的一个潜在点,因为此endpoint直接公开数据库。

因此,在我看来,流2似乎是一个更好的选择,因为它只会在您的数据库和Auth0的数据库之间同步一次。这里唯一的挑战是处理注册后过程中的失败。

另请注意,正如评论中所建议的那样,< code>app_metadata是更适合存储这类信息的地方。

况唯
2023-03-14

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

我发现注册流程1运行得很好。你没有具体说明你在使用哪种技术,但是这里有一个到我的github的链接,在那里我有一个功能齐全的博客,使用了注册流1,React,redux和Express后端。

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

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

我的注册流程如下:

  1. 前端显示锁定用户注册
  2. 用户被重定向到回调页面
  3. 然后,我从回调页面重定向到“身份验证检查”页面。我在auth检查页面中有一个嵌套的api调用,它从auth0获取用户数据,然后立即调用apiendpoint将用户数据保存到数据库
  4. api调用检查用户是否已经在sqldb中,然后保存用户数据,否则什么都不做
  5. 然后将用户数据保存为冗余全局状态,并可用于在用户配置文件页面上显示数据
  6. 当用户单击注销时,再次调用authcheck,并从全局状态中删除用户信息,然后注销用户
  7. 身份验证检查然后重定向回主页

1.前端显示用户注册的锁

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

< br> 2。用户被重定向到回拨页面。

我的回调页面非常简单,它用作功能组件。

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

< br> 3。然后,我从回调页面重定向到“验证检查”页面

我通过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()函数

   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
    }
   }

身份验证中的这两个函数。js-util组件将允许我们从auth0获取信息,并将其保存到我们在类中声明的空对象中。

  userProfile = {}

转到身份验证检查.js容器。我首先在构造函数中声明函数,然后声明函数本身。然后我调用组件DidMount()生命周期方法,该方法在组件呈现时自动运行。

  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('/')))
   }

我的生命周期方法和我返回一个空的 div。

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>
    )
  }
}

我认为这里的这段代码触及了您提出的问题的核心。

我将从 send_profile_to_db() 函数开始。

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

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

export const auth = new Auth();

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

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

这允许我使用“This.props”访问auth类的所有属性。因此,我只需使用上一步中初始化的“userProfile={}”对象,该对象现在包含用户数据。

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

因此,总的来说,这个authcheck组件做了4件事:< br> 1。将我们从auth0获得的用户配置文件数据保存到我们自己的数据库中。< br> 2。然后在保存数据后,立即从我们的数据库中检索相同的配置文件。< br> 3。让我们的应用程序知道用户是否经过身份验证。< br> 4。将我们的数据库用户配置文件数据保存到全局redux状态,以便在其他组件中使用。

非常棒,如果你问我!

4. api调用检查用户是否已经在sql db中,然后保存用户数据,否则什么都不做。

现在这是我的服务器设置。供用户数据库“发布”和“获取”请求。

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 还为您提供了更多数据点,但我最终没有使用它们。

这是我的用户SQL模式表。

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

5.然后将用户数据保存为冗余全局状态,并可用于在用户配置文件页面上显示数据。

我最后只是在第3步解释了这一点。

6.当用户单击注销时,再次调用authcheck,并从全局状态中删除用户信息,然后注销用户。

请参阅步骤 3

7.auth-check然后重定向回主页。

再次见步骤3 lol。

< br >如果你感兴趣或者如果我错过了什么,一定要看看我的回购,就像我说的,这是一个完整的功能齐全的博客。

 类似资料:
  • NativeScript Auth0 Auth0 is a social login provider for NativeScript allowing you to choose between 50 different providers. Use the Auth0 portal to select and configure the providers you would like to

  • 我正在尝试让auth0与quarkus一起工作: 我使用过的资源是: https://github . com/quarkusio/quarkus-quick starts/tree/main/security-oauth 2-quick start https://quarkus.io/guides/security-oauth2 当我转到我的/auth/login页面时,我重定向到我的Auth

  • OAuth 2.0和Auth0有什么区别?我应该使用哪一个来开发认证系统?

  • 我使用这个库Aut0JavaJWT实现了JSON Web令牌,用于使用Spring框架的REST API。 这是密码 只要我使用HTTPS,我的JWT安全吗?我应该使用有效期吗?

  • React Redux Auth0 Kit Minimal starter boilerplate project with React, Redux, React Router and Auth0 authentication Live demo A live demo of this project with a simple Facebook login via Auth0 is avail

  • 我想创建一个应用程序来注册一个新指纹,并在同一个应用程序中添加更多指纹和身份验证,但我只能用硬件支持的指纹对其中一个进行身份验证。 所以我的要求是: 通过应用程序将指纹注册为图像扫描仪,并将其发送到数据库或服务器。 通过数据库或保存指纹的服务器验证同一应用程序中扫描的指纹。 在谷歌示例代码的帮助下,我可以扫描系统的扫描指纹。