一.OAuth2简介

OAuth 2.0(开放授权 2.0)是一种用于授权的开放标准,旨在允许用户在不提供他们的用户名和密码的情况下,授权第三方应用访问其在另一网站上的信息。它是在网络服务之间安全地共享用户资源的流行协议。

以下是OAuth2的主要组成部分和概念:

  1. 资源所有者(Resource Owner):通常是用户,拥有需要被保护的资源,如照片、文件等。

  2. 客户端(Client):请求访问资源的应用,可能是网站、移动应用或其他服务。

  3. 授权服务器(Authorization Server):负责验证用户身份并颁发访问令牌(Access Token)的服务器。

  4. 资源服务器(Resource Server):存储和管理受保护的用户资源,只响应有效的访问令牌。

  5. 授权许可(Authorization Grant):授权服务器颁发给客户端的凭证,用于获取访问令牌。

  6. 访问令牌(Access Token):客户端用于访问资源服务器上受保护资源的令牌。

  7. 刷新令牌(Refresh Token):在访问令牌过期时用于获取新的访问令牌的令牌。

OAuth2的工作流程大致如下:

  • 客户端请求授权,将用户导向授权服务器。
  • 用户登录并同意授权。
  • 授权服务器颁发授权许可。
  • 客户端使用授权许可请求访问令牌。
  • 授权服务器验证请求并颁发访问令牌。
  • 客户端使用访问令牌访问资源服务器上的受保护资源。

OAuth2提供了一种安全的机制,使第三方应用可以在用户授权的情况下访问其受保护的资源,而无需直接获取用户的凭证。这使得用户可以更安全地共享他们的数据。

二.GitHub中的OAuth2

申请GitHub OAuth2应用需要在GitHub上注册一个应用。以下是详细步骤:

  1. 登录GitHub账户: 在GitHub上登录您的账户。

  2. 转至开发者设置: 转至 GitHub开发者设置 页面。

  3. 创建新应用: 点击页面上的“New OAuth App”按钮。

  4. 填写应用信息: 在弹出的表单中填写应用信息,包括应用名称、主页URL、授权回调URL等。

  5. 获取Client ID和Client Secret: 完成表单后,GitHub将为您的应用生成一个唯一的Client ID和Client Secret。这两个值在后续步骤中将用于验证您的应用。

  6. 设置授权范围: 根据您的应用需求,选择适当的授权范围,以确定应用在用户授权时可以访问的资源。

  7. 保存应用设置: 最后,点击“Register application”按钮,保存应用设置。

完成上述步骤后,您的应用就可以使用GitHub OAuth2进行授权了。在实际编写代码时,您将使用刚刚生成的Client ID和Client Secret来获取访问令牌,进而访问用户授权的资源。请确保妥善保管这两个值,以确保安全性。

三.编写授权代码

在这我使用SpringBoot来展开将Github OAuth2授权的具体方式

第一步

将申请到的ClientId和ClientSecret写入配置文件,在这我选择写到SpringBoot的application.yml文件中,然后用@ConfigurationProperties注解映射到实体类。

配置文件:

server:
port: 8080 github:
clientId: yourClientIdHere
clientSecret: yourClientSecretHere

实体类:

package com.github.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; @ConfigurationProperties(prefix = "github")
@Component
@Data
public class GithubConfig { private String clientId; private String ClientSecret; }

在这里就大概配置好了Github OAuth2授权的上下文。

第二步

编写前端代码,这里我选择使用原生HTML来展示页面效果(你也可以编写复杂的页面来实现美观效果)

<!DOCTYPE html>
<html> <head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>OAuth2 Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head> <body>
<a id="login">Login with GitHub</a> <script>
const client_id = 'your_clientId_here'; const authorize_uri = 'https://github.com/login/oauth/authorize';
const redirect_uri = 'http://localhost:8080/oauth/callback'; const link = document.getElementById('login'); function generateSecureRandomString(length) {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const crypto = window.crypto || window.msCrypto;
const randomValues = new Uint32Array(length); crypto.getRandomValues(randomValues); let randomString = "";
for (let i = 0; i < length; i++) {
const randomIndex = randomValues[i] % charset.length;
randomString += charset.charAt(randomIndex);
} return randomString;
} let state = generateSecureRandomString(10)
link.href = `${authorize_uri}?client_id=${client_id}&scope=user:email&redirect_uri=${redirect_uri}&state=${state}`;
</script> </body> </html>

注意在这里总共有四个参数,redirectUrl和state参数最好由后端生成,其中state参数用来防止CSRF攻击,请务必在后端生成,下文会提及如何使用该参数来防止CSRF攻击,关于scope参数请查阅github官方文档

点击页面的Login with GitHub后,会跳转到Github的授权页面

第三步

到了我们的后端主逻辑,在这我们需要携带我们的clientIdClientSecret,来请求Github的地址,授权过后Github将重定向到我们设置的回调地址并返回一个code参数和前文提到的state参数,我们在后端需判定此state参数和我们生成的state参数是否一致,来达到拒绝CSRF攻击的目的,下面我们就可以用Github返回的code参数,配置文件中的clientIdclientSecret参数去请求token了。

package com.github.contoller;

import com.github.config.GithubConfig;
import com.github.entity.AccessTokenResponse;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; @Controller
@RequestMapping("/oauth")
public class IndexController { @Autowired
private GithubConfig githubConfig; // 存储生成的state参数,可以使用更适合线程安全的数据结构,如ConcurrentHashMap
private ConcurrentHashMap<String, String> storedStates = new ConcurrentHashMap<>(); @GetMapping("/params")
public Map<String,Object> getParams(){
//TODO 生成state参数等
return null;
} @GetMapping("/callback")
public String handleRedirect(@RequestParam("code") String requestToken,Model model) {
//TODO 在这判断state参数是否一致 // 使用RestTemplate来发送HTTP请求
RestTemplate restTemplate = new RestTemplate(); // 获取Token的Url
String tokenUrl = "https://github.com/login/oauth/access_token" +
"?client_id=" + githubConfig.getClientId() +
"&client_secret=" + githubConfig.getClientSecret() +
"&code=" + requestToken; // 使用restTemplate向GitHub发送请求,获取Token
AccessTokenResponse tokenResponse = restTemplate.postForObject(tokenUrl, null, AccessTokenResponse.class); // 从响应体中获取Token数据
String accessToken = tokenResponse.getAccessToken(); System.out.println("accessToken = " + accessToken); // 携带Token向GitHub发送请求
String apiUrl = "https://api.github.com/user/emails";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "token " + accessToken);
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
ResponseEntity<String> response = restTemplate.exchange(apiUrl, HttpMethod.GET, entity, String.class); // 将 userData 添加到模型
model.addAttribute("userData", response.getBody()); // 返回视图的逻辑名称
return "welcome";
} }

有关CSRF的具体解释请参照wikipedia,这里不做过多解释。

注:我这里并没有在后端生成state参数,如将代码用于生产环境,请自行改写代码!!!!!

第四步

在请求头中添加access_token就可以去获取相关的信息了

// 携带Token向GitHub发送请求
String apiUrl = "https://api.github.com/user/emails";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "token " + accessToken);
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
ResponseEntity<String> response = restTemplate.exchange(apiUrl, HttpMethod.GET, entity, String.class);

第五步

到这基本上可以说是结束了,你已经获取到了你想要的参数,接下来就看你如何处理你的业务逻辑了。

总结

以上就是GitHub OAuth2的授权指南,其中方法并不完善,本意是学习第三方授权,还请多多见谅。

GitHub OAuth2的授权指南的更多相关文章

  1. Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端

    Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端 目录 前言 OAuth2.0简介 授权模式 (SimpleSSO示例) 使用Microsoft.Owin.Se ...

  2. OAuth2.0开发指南

    OAuth2.0开发指南 1.认证与登录 来往开放平台支持3种不同的OAuth 2.0验证与授权流程: 服务端流程(协议中Authorization Code Flow): 此流程适用于在Web服务端 ...

  3. OAuth2.0学习(2-1)Spring Security OAuth2.0 开发指南

    开发指南:http://www.cnblogs.com/xingxueliao/p/5911292.html Spring OAuth2.0 提供者实现原理: Spring OAuth2.0提供者实际 ...

  4. 新浪微博Oauth2.0授权认证及SDK、API的使用(Android)

    ---------------------------------------------------------------------------------------------- [版权申明 ...

  5. 使用微服务架构思想,设计部署OAuth2.0授权认证框架

    1,授权认证与微服务架构 1.1,由不同团队合作引发的授权认证问题 去年的时候,公司开发一款新产品,但人手不够,将B/S系统的Web开发外包,外包团队使用Vue.js框架,调用我们的WebAPI,但是 ...

  6. Spring Cloud下基于OAUTH2认证授权的实现

    GitHub(spring -boot 2.0.0):https://github.com/bigben0123/uaa-zuul 示例(spring -boot 2.0.0): https://gi ...

  7. Spring Boot 集成 Swagger2 与配置 OAuth2.0 授权

    Spring Boot 集成 Swagger2 很简单,由于接口采用了OAuth2.0 & JWT 协议做了安全验证,使用过程中也遇到了很多小的问题,多次尝试下述配置可以正常使用. Maven ...

  8. 微信 OAuth2 网页授权获取用户信息

    文档:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html !!! 微信跟用户没有关系类接口采用了OAUTH2 [ ...

  9. API代理网关和OAuth2.0授权认证框架

    API代理网关和OAuth2.0授权认证框架 https://www.cnblogs.com/bluedoctor/p/8967951.html 1,授权认证与微服务架构 1.1,由不同团队合作引发的 ...

  10. Spring Security实现OAuth2.0授权服务 - 基础版

    一.OAuth2.0协议 1.OAuth2.0概述 OAuth2.0是一个关于授权的开放网络协议. 该协议在第三方应用与服务提供平台之间设置了一个授权层.第三方应用需要服务资源时,并不是直接使用用户帐 ...

随机推荐

  1. Aoba's GitLab Doki Theme - 一个简单的 GitLab 主题工具

    前言 平常工作在用 GitLab 但总觉得缺点什么颜色好单调,于是随手摸了一个主题工具 界面预览 GitLab 主页效果 个人偏好配置页面 安装方法 安装 Tampermonkey 之类的用户脚本工具 ...

  2. UVA10054 The Necklace 题解

    好可恶一道题,怎么没人告诉我输出之间有空行( 思路是先抽象成图,然后跑一边dfs记录边的前后顺序. 对于不能成环的情况,只需要再开个数组记录度数判断奇点即可. 若存在奇点则break掉,剩下的跑dfs ...

  3. 惊奇!Android studio内部在调用Eclipse

    现在用Android studio的人越来越多,主要是说谷歌不再支持Eclipse,而力推Android studio.但是as也太不给力了,我之前写过一篇博客提到. 今天要说的是一个惊天的消息,如题 ...

  4. 深入理解 Netty FastThreadLocal

    作者:vivo 互联网服务器团队- Jiang Zhu 本文以线上诡异问题为切入点,通过对比JDK ThreadLocal和Netty FastThreadLocal实现逻辑以及优缺点,并深入解读源码 ...

  5. 源码搭建zabbix平台

    1.基于lnmp部署zabbix监控平台; zabbix优点: 1.支持自动发现服务器和网络设备: 2.分布式的监控体系和集中式的WEB管理: 3.支持主动监控和被动监控模式: 4.基于SNMP.IP ...

  6. 码编译安装nginx

    1.解释源码安装nginx软件的预编译,编译以及安装,分别是在做什么,需要注意什么? 预编译(configure): ./configure 00prefix=/usr/local/nginx --u ...

  7. python代码签到学习同

    仅用于学习使用 import requests,json,time #填入Cookie headers={ "Cookie": "", "User-A ...

  8. springboot项目在docker中运行

    前端时间需要把项目打包到docker中运行,于是就让组员去探索,最后整个过程是这样的. 首先我们做java开发,一般都是使用springboot开发,开发完成,我们需要把springboot项目打包成 ...

  9. 全网最详细4W字Flink全面解析与实践(下)

    本文已收录至GitHub,推荐阅读 Java随想录 微信公众号:Java随想录 原创不易,注重版权.转载请注明原作者和原文链接 承接上篇未完待续的话题,我们一起继续Flink的深入探讨 Flink S ...

  10. 用python计算圆周率PI,并显示进度条

    用python计算圆周率PI ‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪ ...