likes
comments
collection
share

部署阿里云云函数舒畅无阻的请求 Github OpenApi 实现 OAuth2.0 登录

作者站长头像
站长
· 阅读数 7

这篇小短文没什么技术价值,主要是实用价值,希望能帮助到有这个需求的朋友

在自己建站的过程中,想要实现登录功能其实并不是一个简单的活儿,它的主要难点不在于技术实现,而是难在独立开发者往往没有太多资金投入。

举个例子,如果我现在要实现一个手机号码短信登录,先不考虑用户意愿问题,我们需要购买的第一个第三方服务就是短信发送的服务,每发送一条短信验证码,都是真金白银的钱,为了防止被人恶意刷量,还要购买行为验证码(或风控相关的)服务,这背后要多少钱大家可以自行了解下。

换个思路,我们支持微信登录好了,结果一查要注册公司盖章提交审核,才能使用微信的第三方登录功能,还要每年交个 300 元。所以可选择的不多,Github OAuth 登录是我的首选项,因为大多数开发者都会有自己的 Github 账号,而 Github OAuth 登录又没有类似微信的各种限制。

不过问题是,Github 登录过程中要调用它的 OpenApi,如果你和我一样买的是大陆的云服务器,会经常超时,这非常令人头疼,修改 host 什么的根本卵用没有,买国外的服务器又死贵。不过好在阿里云的 FC(云函数)产品还是挺便宜的,接下来就介绍下如何利用云函数调用 OpenApi,而国内服务器又能调该云函数获取返回结果。

前提

因为我购买的是阿里云的 FC 产品,所以你最好也是和我一样,有一个阿里云账号,如果你还没购买,新用户可以试用三个月。

打开控制台

找到产品函数计算 FC,点击【管理控制台】。

部署阿里云云函数舒畅无阻的请求 Github OpenApi 实现 OAuth2.0 登录

进入之后,你会看到账号下的基础信息。

部署阿里云云函数舒畅无阻的请求 Github OpenApi 实现 OAuth2.0 登录

创建服务

找到左边菜单的【服务及函数】按钮,点击跳转后,将注意力移到最上方,地理位置选择美区(只要不是大陆地区就行),非常重要!

部署阿里云云函数舒畅无阻的请求 Github OpenApi 实现 OAuth2.0 登录

接着我们点击【创建服务】,名称随便填写,最好和我们要实现的功能相近。打开【高级选项】,我们要选择一个角色,没有的话,点下面创建一个就行。

部署阿里云云函数舒畅无阻的请求 Github OpenApi 实现 OAuth2.0 登录

创建函数

服务创建完成后,我们就可以开始创建云函数,点击【创建函数】。

部署阿里云云函数舒畅无阻的请求 Github OpenApi 实现 OAuth2.0 登录

选择【使用自定义运行时创建】,函数名称写一个比较贴近函数功能的名字,请求处理程序类型选择【处理 HTTP 请求】,运行环境推荐选比较稳定的 Node.js 16,代码上传方式我选择的是【使用示例代码】,这样我们可以知道如何写一个 Hello World 级别的云函数,并正确调用后慢慢实现我们的功能函数。

部署阿里云云函数舒畅无阻的请求 Github OpenApi 实现 OAuth2.0 登录

其它的选项我们都可以先使用默认的,点击底部【创建】按钮完成创建。

调用云函数

创建完成后,来到这一个选项卡【触发器管理(URL)】,就可以看到我们的访问地址了。

部署阿里云云函数舒畅无阻的请求 Github OpenApi 实现 OAuth2.0 登录

在选项卡【函数代码】中可以直接编写我们的接口,【测试函数】能够进行接口调用测试,都是很实用的,这里我们先打开【函数代码】看看写了啥。

部署阿里云云函数舒畅无阻的请求 Github OpenApi 实现 OAuth2.0 登录

可以看到我们的接口代码,使用 Apifox 调用下这个接口测试下。

部署阿里云云函数舒畅无阻的请求 Github OpenApi 实现 OAuth2.0 登录

返回正确,证明我们的云函数部署成功了。接下来就可以大施拳脚改造我们的请求接口,实现 Github Openapi 的调用了。

比如我主要是实现 OAuth2.0 登录,代码如下:

const express = require('express');
const bodyParser = require('body-parser');
const axios = require('axios')

const app = express();

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(bodyParser.raw());

const port = 9000

app.get('/oauth/access_token', async (req, res) => {
  let errorMsg
  let tokenResponse = {}

  try {
    const { client_id, client_secret, code } = req.query
    tokenResponse = await axios({
      method: 'post',
      url:
        'https://github.com/login/oauth/access_token?' +
        `client_id=${client_id}&` +
        `client_secret=${client_secret}&` +
        `code=${code}`,
      timeout: 6000,
      headers: {
        accept: 'application/json',
      },
    })
  } catch (error) {
    errorMsg = error
  }

  res.send(errorMsg ? {
    errorMsg
  } : {
    ...tokenResponse.data
  })
})

app.get('/oauth/user_info', async (req, res) => {
  let errorMsg
  let githubUserInfo = {}

  try {
    const { access_token } = req.query
    githubUserInfo = await axios({
      method: 'get',
      url: 'https://api.github.com/user',
      timeout: 6000,
      headers: {
        accept: 'application/json',
        Authorization: `token ${access_token}`,
      },
    })
  } catch (error) {
    errorMsg = error
  }

  res.send(errorMsg ? {
    errorMsg
  } : {
    ...githubUserInfo.data
  })
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

上面我写了两个接口,没在同一个接口实现两个接口的请求是因为会 401,但是分开就可以,这里非常奇怪,我也不知道是哪里问题,非常奇怪。

最后

现在你就可以在自己服务端去调这些你写好的接口了,比如我的调用如下:

async oauthGithubLogin(oauthGithubLoginDto: OAuthGithubLoginDto) {
  const { code } = oauthGithubLoginDto

  let tokenResponse: any = {}
  let githubUserInfo: any = {}

  try {
    tokenResponse = await axios({
      method: 'get',
      url:
        'https://github-auth-api-github-openapi-phktxmgeeb.us-east-1.fcapp.run/oauth/access_token?' +
        `client_id=${OAUTH_GITHUB_CLIENT_ID}&` +
        `client_secret=${OAUTH_GITHUB_CLIENT_SECRET}&` +
        `code=${code}`,
      timeout: 6000,
    })
  } catch (error) {
    throw new RequestTimeoutException('Request github openapi timed out.')
  }

  try {
    const { access_token: accessToken } = tokenResponse.data || {}
    githubUserInfo = await axios({
      method: 'get',
      url: 'https://github-auth-api-github-openapi-phktxmgeeb.us-east-1.fcapp.run/oauth/user_info?' + `access_token=${accessToken}`,
      timeout: 6000,
    })
  } catch (error) {
    throw new RequestTimeoutException('Request github openapi timed out.')
  }

  console.log(githubUserInfo)
  // 后续逻辑
}

好了,终于可以愉快调用 Github 的 OpenApi 了,整就一个舒畅。

转载自:https://juejin.cn/post/7319700227525836835
评论
请登录