给你的网站添加第三方登陆以及短信验证功能

OAuth 2.0 是目前最流行的受权机制,用来受权第三方应用,获取用户数据。好比掘金这种第三方帐号 微信、微博、github 登陆方式同样。思考一下这种登陆方式是如何设计和实现的呢?平常生活中不少APP或者网站在用户输入完手机号以后都须要发送验证码校验,那么这整套流程又是如何实现的呢? 前端

掘金登陆

1、OAuth的思路

OAuth在“客户端”和“服务供应商”之间,设置了一个受权层。“客户端”不能直接登陆“服务供应商”,只能登陆受权,以此将用户与客户端区分开来。“客户端”登陆受权以后,“服务提供商”根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。 ios

简单说,OAuth 就是一种受权机制。数据的全部者告诉系统,赞成受权第三方应用进入系统,获取这些数据。系统从而产生一个短时间的进入令牌(token),用来代替密码,供第三方应用使用。git

2、OAuth的登陆实践

以GitHub为例子,实现OAuth的受权登陆。接下来我会一步步实践如何在你的网站中接入github受权登陆 github

一、GitHub 应用登记

点击按钮去github主页新建一个OAuth App,点击建立 按以下提示填写信息sql

建立完以后记住页面上方的 Client ID 和 Client Secret,后面开发时须要用到这两个参数。

二、代码实现

2.1 前端实现

前端采用了掘金的受权登陆方式,当用户点击第三方GitHub登陆,弹出一个新窗口json

window.open("/oauth", "", "height=600, width=700")axios

在这个新窗口里只须要跳转连接,client_id,redirect_uri 就是以前建立的参数配置本身的就行。后端

window.location.href = 'github.com/login/oauth…' 用户受权登陆以后会跳到redirect页面,在redirect请求后端带上刚产生的code,后端拿到code请求github获得的用户信息资料,最后关闭弹窗。api

2.2 后端实现

后端做者采用的是Koa2,代码以下bash

router.get('/oauth', async function(ctx, next) {
  const requestToken = ctx.request.query.code
  const tokenResponse = await axios({
    method: 'post',
    url: 'https://github.com/login/oauth/access_token?' +
      `client_id=${OAUTH_GITHUB.clientID}&` +
      `client_secret=${OAUTH_GITHUB.clientSecret}&` +
      `code=${requestToken}`,
    headers: {
      accept: 'application/json'
    }
  })
  const accessToken = tokenResponse.data.access_token
  const result = await axios({
    method: 'get',
    url: `https://api.github.com/user`,
    headers: {
      accept: 'application/json',
      Authorization: `token ${accessToken}`
    }
  })
复制代码

后面根据本身的业务需求,将获取到的信息存入到用户表中。这里的方式不少,我是直接将github受权登陆的信息插入到个人用户表里,或者你新建一个第三方oauth表去存放也是能够的。

const oauthLogin = async (userData = {}) => {
  const username = userData.username
  const nickname = userData.username
  const avatar = userData.avatar
  const date = Date.now()
  const userSql = `select * from users where username = '${username}' `
  const rows = await exec(userSql)
  if (rows.length > 0) {
    return rows[0] || {}
  } else {
    const sql = `insert into users (username,password, nickname, avatar, date) values ('${username}', '${password}', '${nickname}', '${avatar}', '${date}');`
    const insertData = await exec(sql)
  }
}
复制代码

最后的效果

3、短信验证登陆

3.1 开通短信服务

短信验证天然须要用到服务商,阿里云有免费短信开通功能,免费开通短信服务,开通以后按每条0.04元计算。为了练习充了一元测试短信验证功能,免费开通这个仍是很是的好的,不用发不少钱就能够上手测试

3.2 前端实现

仍是拿掘金的案例来说,用户点击注册输入手机号以后,点击获取验证码。

3.3后端实现

router.post('/sendSmsCodeToUser', async function (ctx, next) {
  const { username } = ctx.request.body
  CODE = Math.random().toString().slice(-6)
  var client = new RPCClient({
    accessKeyId: 'LTAI4FcGip5kqy1', // 本身申请短信的
    accessKeySecret: 'BvmhpNobez41as1vA5z1QSbhTGIm', 
    endpoint: 'https://dysmsapi.aliyuncs.com',
    apiVersion: '2019-12-14'
  })
  var params = {
    "RegionId": "cn-hangzhou",
    "PhoneNumbers": `${username}`,
    "SignName": "起航网",
    "TemplateCode": "SMS_180059442",
    "TemplateParam": `{code: ${CODE}}`
  }
  var requestOption = {
    method: 'POST'
  }
  var result = await client.request('SendSms', params, requestOption).then((res) => {
      return res
    }, (ex) => {
      return ex
    })
  if ('Code' in result) {
    ctx.body = new SuccessModel({message: '验证码发送成功'})
  } else {
    const limit = result.data.Message.split(':')[1]
    ctx.body = limit >= 10 ? new ErrorModel({message: '同一手机号天天只能发送 10 条验证码'}) : new ErrorModel({message: '同一手机号每小时只能发送 5 条验证码'})
  }
})
复制代码

先后端请求对比CODE,实现短信验证登陆功能

相关文章
相关标签/搜索