GitHub OAuth第三方登录示例教程(Node后端)

1.第三方登录的原理

所谓第三方登录,实质就是 OAuth 授权。用户想要登录 A 网站,A 网站让用户提供第三方网站的数据,证明自己的身份。获取第三方网站的身份数据,就需要 OAuth 授权。

举例来说,A 网站允许 GitHub 登录,背后就是下面的流程。

  1. A 网站让用户跳转到 GitHub
  2. GitHub要求用户登录,然后询问"A 网站要求获得 xx 权限,你是否同意?"
  3. 用户同意,GitHub就会重定向回 A 网站,同时发回一个授权码。
  4. A 网站使用授权码,向 GitHub请求令牌。
  5. GitHub返回令牌.
  6. A 网站使用令牌,向 GitHub请求用户数据。

2.创建应用

跳转创建应用界面

详细⬇️

  1. 进入Github ⬇️

  2. 点击头像 ➡️ Settings

  3. 左侧侧边栏最底下➡️ Developer settings

  4. 左侧侧边栏第二个➡️ OAuth Apps

  5. 右侧内容区➡️ New OAuth App

  6. 填写相关信息

    image-20220803171712178

    1. 点击注册应用后,生成一个Client secrets

      image-20220803172004707

    2. 只会出现一次Client secrets,自己保存好

      image-20220803172119335

3. 示例仓库

我写了一个代码仓库,请将它克隆到本地。

git clone https://github.com/ivwv/GitHub-OAuth-Demo.git
cd GitHub-OAuth-Demo

app.js中写入自己的自己的clientIdclientSecret

const clientId = "YOUR_CLIENT_ID";
const clientSecret = "YOUR_CLIENT_SECRET";

安装依赖并启动服务

npm install
node app.js

浏览器访问http://localhost:3000,就可以看到这个示例了。

4.浏览器跳转 GitHub

示例的首页很简单,就是一个链接,让用户跳转到 GitHub

image-20220803172843930

跳转的URL为:

<h1>
  <a href="/github-login">GitHub OAuth登录</a>
</h1>
  • 请求路径为https://github.com/login/oauth/authorize
  • 请求参数为:client_id,redirect_uri,scope更多参数点击查看Github Docs
  • client_id是必须的
  • redirect_uri是可选的,
    • 不填的前提是在创建应用时添加了完整了回调地址
    • 否者这里就要添加回调地址参数
// 登录跳转是通过这个
app.get("/github-login", (req, res) => {
  res.redirect(
    `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=http://localhost:3000/oauth-callback&scope=user:email`
  );
});

最后跳转到这个地址

https://github.com/login/oauth/authorize?client_id=d7c2ef54200bd4b6cc7d&redirect_uri=http://localhost:3000/oauth-callback&scope=user:email

5.用户授权

用户确定授权

image-20220803174239770

用户确定授权后,会跳转到自己创建的回调地址,我们可以在回调地址内填写自己需要的相关操作

app.get("/oauth-callback", async (req, res) => {})

1.获取access_token

/oauth-callback路由内发送请求获取access_token⬇️

相关参数请查看Github Docs

const body = {
    client_id: clientId, // 必须
    client_secret: clientSecret, // 必须
    code: req.query.code, // 必须,这个不用我们填写,当授权跳转后,会在/oauth-callback 自动添加code
  };
const opts = { headers: { accept: "application/json" } };
const response = await axios.post(
  `https://github.com/login/oauth/access_token`,
   body,
   opts
);
console.log(response.data);

输出如下内容

{
  access_token: 'gho_qbdcghN1Ar6EkBZX6ghvNGkjMDXlV3eh3AVfYR',
  token_type: 'bearer',
  scope: 'user:email'
}

access_token保存起来,后面的请求都需要添加 headers->Authorization

2.获取用户信息

同样,接下来在/oauth-callback路由内发送请求获取相关用户信息⬇️

相关参数请查看Github Docs

const token = await response.data["access_token"];
  const userinfo = await axios.get(`https://api.github.com/user`, {
    headers: {
      // 在请求头中添加 Authorization 字段
      Authorization: `token ${token}`,
    },
  });
  console.log(userinfo.data);

打印输出⬇️

{
  login: 'ivwv',
  id: 99484154,
  node_id: 'U_kggsBedw0NA',
  avatar_url: 'https://avatars.githubusercontent.com/u/99464244?v=4',
  gravatar_id: '',
  url: 'https://api.github.com/users/ivwv',
  html_url: 'https://github.com/ivwv',
  followers_url: 'https://api.github.com/users/ivwv/followers',
  following_url: 'https://api.github.com/users/ivwv/following{/other_user}',
  gists_url: 'https://api.github.com/users/ivwv/gists{/gist_id}',
  starred_url: 'https://api.github.com/users/ivwv/starred{/owner}{/repo}',
  subscriptions_url: 'https://api.github.com/users/ivwv/subscriptions',
  organizations_url: 'https://api.github.com/users/ivwv/orgs',
  repos_url: 'https://api.github.com/users/ivwv/repos',
  events_url: 'https://api.github.com/users/ivwv/events{/privacy}',
  received_events_url: 'https://api.github.com/users/ivwv/received_events',
  type: 'User',
  site_admin: false,
  name: 'ivwv',
  company: null,
  blog: '',
  location: null,
  email: null,
  hireable: null,
  bio: null,
  twitter_username: null,
  public_repos: 20,
  public_gists: 1,
  followers: 2,
  following: 9,
  created_at: '2022-02-11T05:37:25Z',
  updated_at: '2022-07-28T13:44:24Z'
}

到这里相关信息就出来了,可以看到用户名,头像链接.

但是可以看到emailnull

好像是因为用户没有将邮箱公开

其实也可以获取,请往下看⬇️

3.获取用户邮箱

如果不需要用户邮箱,可以忽略这一步

详细API请看官方文档

在上面两个请求后面,添加如下内容

const emailinfo = await axios({
    method: "get",
    url: "https://api.github.com/user/emails",
    headers: {
      Accept: "application/vnd.github+json",
      Authorization: `token ${token}`,
    },
  });
  console.log(emailinfo.data);

打印输出

[
  {
    email: '*********@gmail.com',
    primary: true,  // primary为tuer表示该用户主要登录邮箱,false则为辅助邮箱
    verified: true,
    visibility: 'private'   // 这里为private表示在上一个请求的email为null,如果是public这上一个请求可以展示邮箱
  },
  {
    email: '***********.com',
    primary: false,
    verified: true,
    visibility: null
  },
  {
    email: '******@qq.com',
    primary: false,
    verified: true,
    visibility: null
  }
]

6.完成授权

接下来就是在路由内继续添加自己的需求,可以是将用户信息保存在数据库

// TODO: 将用户信息和邮箱信息保存到数据库中
  // ...

  // 验证成功,跳转到首页
  res.redirect(`/index.html`);

友情提示

当点击授权后,Github以及将你本次的登录状态保存,下一次再测试将不会经过你授权

需要进入应用管理 将状态移除,再执行授权

image-20220803182450628

本人博客地址 欢迎查看 https://ivwv.github.io

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vvw&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值