热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《Auth0:在Auth0注册后在本地数据库中创建用户》经验,为你挑选了1个好方法。

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

注册流程1:

    前端显示Lock,用户注册.

    Auth0重定向回前端后,前端有Auth0 user_id.

    前端调用后端POST /users(公共端点)以创建新用户user_id.

    在对我的后端资源服务器的每个经过身份验证的请求中,JWT包含auth0 user_id,因此db在user_id和我之间进行查找userId.

注册流程2:

    前端显示Lock,用户注册.

    在Auth0上配置一个后注册挂钩,用于调用POST /users我的后端.此调用将生成我的数据库userId并将其发送回Auth0.

    把它userId放到Auth0中user_metadata.

    user_metadata将包含在JWT中,因此对我的后端获取资源的所有调用都将包含db userId(不需要额外的查找).

我觉得2更坚固.还有其他注册流程吗?一些auth0客户是否使用与我的#2类似的流程?我在他们的文档中找不到多少.



1> 小智..:

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

我发现注册流程1工作得很好.你没有指定你正在使用哪种技术,但这里有一个指向我的github的链接,我有一个功能齐全的博客,使用注册流程1与React,redux和Express后端.

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

我将演示这些框架,以便您可以调整您正在使用的框架的代码.

我的注册过程如下:

    前端显示Lock用户注册

    用户被重定向到回调页面.

    然后,我从回调页面重定向到"auth-check"页面.我在auth-check页面中有一个嵌套的api调用,它从auth0获取用户数据,然后立即调用api端点将用户数据保存到db.

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

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

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

    验证然后重定向回主页.



1.前端显示Lock用户注册

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


2.用户被重定向到回调页面.

我的回调页面非常简单,我将其用作功能组件.

  

Callback


3.然后,我从回调页面重定向到"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()函数

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

我的生命周期方法和我返回一个空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 (
        
) } }

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

我将从send_profile_to_db()函数开始.

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

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

export const auth = new Auth();

然后将其作为支持传递给AuthCheck组件.

 } />

这允许我使用"this.props"访问auth类的所有属性.所以我只使用我们在最后一步中初始化的"userProfile = {}"对象,该对象现在包含我们的用户数据.

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

总而言之,这个authcheck组件正在做4件事:
1.将我们从auth0获得的用户配置文件数据保存到我们自己的数据库中.
2.然后在保存数据后,立即从我们的数据库中检索相同的配置文件.
3.让我们的应用程序了解用户是否经过身份验证.
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.然后将用户数据保存到redux全局状态,并可用于在用户配置文件页面上显示数据.

我最后在第3步中解释了这一点.



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

见第3步



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

再次看到第3步大声笑.


如果你感兴趣或者我错过了任何东西,请务必查看我的回购,就像我说它是一个完整的功能齐全的博客.


推荐阅读
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
author-avatar
牛氏学道_246
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有