如何使用 OAuth 接入第三方用户信息

「LeanCloud Web 应用开发实践」系列直播及文章分享持续进行中。
每周二周四晚上 8 点开始,时长预计 45 分钟。在 “leanCloud通讯” 微信公众号回复 “公开课” 即可获取直播链接。

点击查看完整公开课视频

OAuth 简介 01:34

OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。维基百科

提示:需要用户在别的网站上的私密信息时,直接向用户要账号密码有点太不专业了。

以 Ticket 为例,转换下说法就是:

允许用户让 Ticket 应用访问该用户在 LeanCloud 上存储的私密资源(如账号,应用列表),而无需将用户名和密码提供给 Ticket。

使用 Ticket 为例,介绍 OAuth 授权过程 04:20

预备工作
  1. Ticket 向 LeanCloud 申请 OAuth 接入。
  2. LeanCloud 审核通过后,给 Ticket 颁发 clientIdclientSecret
用户申请授权 06:15

1.用户访问 Ticket 应用,当 Ticket 需要用户在 LeanCloud 上的信息时(比如 Ticket 想使用用户在 LeanCloud 上的信息来注册自己的网站),OAuth 授权过程开始。

2.Ticket 服务端拼接 LeanCloud 的授权地址给用户,并附带一些信息,包括:

  • clientId:准备工作里面 LeanCloud 办法给 Ticket 的 clientId。
  • scope:Ticket 希望获取用户在 LeanCloud 上信息的范围,比如只要基本账户信息,或者再加上应用列表信息等。
    注意:不是要的信息越多越好,用户可能因为应用需要的信息过多而放弃授权。
  • callbackUrl:当用户确认授权之后,将会跳转回来的页面。

3.用户浏览器根据刚才的响应,跳转到 LeanCloud 的授权页面。LeanCloud 授权页面会展现一些信息:

  • LeanCloud 当前登录用户(如果没有登录会要求登录)。
  • 哪个系统需要获取 LeanCloud 上的权限,因为授权页的请求地址有 clientId
  • 获取什么权限,因为授权页的请求地址有 scope

用户根据这些信息判断是否同意授权:如果取消,OAuth 授权流程终止;如果同意,LeanCloud 会生成一个重定向请求到 Ticket,并在请求上附带一个属性 code。该 code 在 LeanCloud 内部会记录,并且和 Ticket 应用,还有当前授权用户关联。至于调转到 Ticket 的哪个地址,由刚才 Ticket 重定向过来时候的 callbackUrl 决定。

  1. 用户浏览器根据重定向请求继续访问 Ticket 的相关页面,并携带了 code 信息。Ticket 服务端会向 LeanCloud 发起请求,获取用户的 accessToken 信息,请求会携带一些参数:
  • clientId:准备工作里面 LeanCloud 办法给 Ticket 的 clientId

  • clientSecret:准备工作里面 LeanCloud 办法给 Ticket 的 clientSecret

  • code:确认授权后,LeanCloud 返回给用户,再通过用户浏览器页面重定向跳转提交到 Ticket。

LeanCloud 根据参数信息就能确定是哪个应用要获取哪个用户的 accessToken,如果所有信息确认无误,则返回 accessToken

提示:clientSecret 是私密的,不能泄漏,建议不要直接配置在项目代码中。如果部署在云引擎,建议使用云引擎的环境变量来保存这些数据。云引擎环境变量设置方式: LeanCloud 控制台 -> 云引擎 -> 设置 -> 自定义环境变量,增加需要的变量名和变量值,点保存,下次部署时生效。
  1. 当 Ticket 服务端拿到用户的 accessToken 之后,就可以通过该信息作为凭证去请求这用户的信息(当然需要在 scope 的范围内)。

至此,OAuth 授权结束。

相关代码介绍 25:26
本期视频使用的代码地址:github.com/leancloud/t…

版本:664259e

可以使用下面的命令获取:

git clone https://github.com/leancloud/ticket.git
cd ticket
git checkout 664259e复制代码

整个流程涉及到的代码部分:

  1. 用户登录页关于 OAuth 授权的代码 modules/Login.js
<div className={css.wrap}>
  <h1 className='font-logo'>欢迎回来</h1>
  <hr />
  <p>目前只支持通过 {ORG_NAME} OAuth 授权进行登录</p>
    <a href='/oauth/login' className='btn btn-primary'>前往 {ORG_NAME} 授权页</a>
</div>复制代码

可见,当用户点击「前往 LeanCloud 授权页」按钮是,将请求 GET /oauth/login 路由。

  1. 服务端的路由定义在 api/index.js
...
router.use('/oauth/login', require('./oauth').login(loginCallbackUrl))
...复制代码

路由方法定义在 api/oauth.js 的 login 方法中

exports.login = (callbackUrl) => {
  return (req, res) => {
    const loginUrl = serverDomain + '/1.1/authorize?' +
      qs.stringify({
        client_id: config.oauthKey,
        response_type: 'code',
        redirect_uri: callbackUrl,
        scope: oauthScope,
      })
    res.redirect(loginUrl)
  }
}复制代码

该方法接受一个 callbackUrl 参数,返回一个 express 的路由方法(即接收 requestresponse 为参数的方法)。在这个路由方法中拼接了 LeanCloud 授权页的请求,然后向客户端回复一个 302 响应(由 res.redirect() 方法实现)。

  1. 用户浏览器跳转到 LeanCloud 授权页,授权成功后,用户浏览器重定向到 Ticket 的 相关路由定义
...
router.use(loginCallbackPath, require('./oauth').loginCallback(loginCallbackUrl))
...复制代码

路由的 具体实现

exports.loginCallback = (callbackUrl) => {
  return (req, res) => {
    getAccessToken(req.query.code, callbackUrl).then((accessToken) => {
      accessToken.uid = '' + accessToken.uid
      return AV.User.signUpOrlogInWithAuthData(accessToken, 'leancloud')
    }).then((user) => {
      if (_.isEqual(user.createdAt, user.updatedAt)) {
        // 第一次登录,从 LeanCloud 初始化用户信息
        return initUserInfo(user)
      }
      return user
    }).then((user) => {
      res.redirect('/login?token=' + user._sessionToken)
    })
  }
}复制代码

可见路由的实现中:

  1. 先使用请求携带的 code 信息到 LeanCloud 网站获取该用户的 accessToken(详见 getAccessToken)。
  2. 使用 JS SDK 的 AV.User.signUpOrlogInWithAuthData() 的方法来注册或者登陆用户(根据是否有相同授权信息的用户决定)。这样注册的用户,账号和密码都是随机生成,_User 表的 authData 列会保存用户在对应平台的授权信息。
  3. 如果用户是第一次登陆,则使用该用户在 LeanCloud 上的 usernameemail 信息来设置用户在 Ticket 里的信息(详见 initUserInfo1)。
  4. 生成 302 响应,并将用户的 sessionToken 作为 queryString,进行客户端登录(res.redirect('/login?token=' + user._sessionToken))。
  • 客户端收到服务端响应后,使用 sessionToken 进行客户端登录,代码 modules/Login.js
const query = nextProps.location.query
if (query.token) {
  return AV.User.become(query.token)
  ...
}复制代码

至此,OAuth 授权,以及服务端创建(或登录)用户,以及客户端同步登录过程全部结束。

如果需要用户在 LeanCloud 上的其他信息,Ticket 服务端可以使用用户的 accessToken_User表的authData 属性中)来获取,可以参考这些方法:

  • getClientInfo:获取用户基本信息
  • getApps:获取用户在 LeanCloud 上的应用列表。
  • getApp:获取用户在 LeanCloud 上某个应用的详情。
  • getAccount:获取用户在 LeanCloud 上账户的详情,主要用来判断是否有权限提交工单。

其他说明 45:08

我们只介绍了 OAuth 的最基本流程,以及最必要的请求参数,至于 OAuth 授权为何需要这些步骤,以及每一步的某些参数为何要这样设计,建议大家参考更详细的文档或协议说明。

如果自己的应用要申请别的网站 OAuth 授权(比如 QQ),可以查看对应网站提供的 OAuth 相关文档。

如果要自己实现 OAuth Server,不需要自己实现,各个语言都有相关的库,能极大的降低实现成本。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值