Spring Boot实现Oauth2认证授权登录Github
OAuth2 原理介绍
OAuth2 是一种授权框架,允许第三方应用获取有限的资源访问权限,而无需暴露用户的密码。
核心角色
- Resource Owner(资源所有者):用户
- Client(客户端):第三方应用
- Authorization Server(授权服务器):负责认证和授权
- Resource Server(资源服务器):存储受保护资源
四种授权模式
- 授权码模式(最安全,适合服务端应用)
- 密码模式(用户直接提供密码给客户端)
- 客户端凭证模式(客户端以自己的名义访问)
- 隐式模式(已废弃,不推荐)
工作流程总结
- 用户访问客户端应用
- 客户端重定向用户到授权服务器
- 用户在授权服务器登录并授权
- 授权服务器返回授权码给客户端
- 客户端使用授权码向授权服务器请求令牌
- 授权服务器验证授权码,返回访问令牌
- 客户端使用访问令牌访问资源服务器上的受保护资源
实际调用流程
sequenceDiagram
participant User as 用户
participant Front as 前端
participant Auth as AuthService
participant Provider as GitHub/Google OAuth
participant DB as 数据库
User->>Front: 点击 "GitHub 登录" 按钮
Note over Front: 生成/读取 device_id<br/>拼接到 URL
Front->>Front: window.location.href =<br/>"auth.dengwei.site/api/auth/oauth/github?device_id=xxx"
Note over Front: 页面跳离,进入 OAuth 流程
Front->>Auth: GET /api/auth/oauth/github?device_id=xxx
Auth->>Auth: 生成 state_device_id (防CSRF + 设备标识,device_id可选)
Auth-->>User: 302 重定向到 GitHub 授权页
User->>Provider: 在 GitHub 上授权
Provider-->>Auth: 302 到 callback<br/>GET /oauth/github/callback?code=xxx&state=uuid|device_id
Auth->>Auth: 从 state 提取 device_id
Auth->>Provider: 用 code 换 access_token
Provider-->>Auth: access_token + 用户信息
Auth->>DB: 查询 user_oauth_bindings<br/>(provider + provider_user_id)
alt 已有绑定记录
DB-->>Auth: 关联的 user_id
else 首次登录,自动创建
Auth->>DB: INSERT users
Auth->>DB: INSERT user_oauth_bindings
end
Auth->>DB: 删除该设备旧 refresh_token<br/>DELETE WHERE user_id + client_id
Auth->>Auth: 签发 JWT (access + refresh)
Auth->>DB: 存储新 refresh_token_hash + client_id
Note over Auth: 设置 HttpOnly Cookie:<br/>Set-Cookie: access_token=...<br/>Set-Cookie: refresh_token=...
Auth-->>Front: 302 → test.dengwei.site/oauth/callback
Note over Front: 页面跳转回前端<br/>URL 中无 token (全在 cookie 里)
Front->>Front: 组件挂载 → 立即 Navigate("/")
Front->>Auth: GET /api/auth/me (cookie 自动附带)
Auth-->>Front: { id, email, display_name, avatar_url }
Front->>Front: AuthContext.dispatch<br/>{ type: 'LOGIN_SUCCESS' }
Front-->>User: 已登录,显示首页 ✅
说明:
- 查询到用户信息后的处理逻辑自己可以根据需要修改,如是否替换原有头像等
- 签发新的access_token和refresh_token后,返回给前端的方式有多种,可以使用URL的hash拼接。
- 是否需要区分设备client_id看自己需要
接口
-
/api/auth/oauth/github启动授权流程,这里由后端触发,前端处理也可以。用于拼接URL,重定向到Github授权页面,回调地址写下面的callback地址。 -
/api/auth/oauth/github/callback接收Github的回调,包含授权码,通过授权码再去获取access_token -> 通过access_token查询用户信息 -> 自定义处理用户信息 -> 生成自己服务的access_token和refresh_token返回给前端
本地测试方法
我是用的是Cloudflare的tunnels,安装好服务后,将本地的前端和后端绑定到两个域名上,进行测试的。
Github需要在Settings/Developer Settings/OAuth Apps 下添加一个client。
// 重定向地址
@Override
public String getAuthorizeUrl(String redirectUri, String state) {
return UriComponentsBuilder.fromHttpUrl("https://github.com/login/oauth/authorize")
.queryParam("client_id", clientId)
.queryParam("redirect_uri", redirectUri)
.queryParam("state", state)
.queryParam("scope", "read:user,user:email")
.build()
.toUriString();
}
@Override
protected String getUserInfoUrl() {
return "https://api.github.com/user";
}
@Override
protected String getTokenUrl() {
// 通过code换取access_token
return "https://github.com/login/oauth/access_token";
}
protected MultiValueMap<String, String> buildTokenRequestBody(String code, String redirectUri) {
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("client_id", clientId);
body.add("client_secret", clientSecret);
body.add("code", code);
body.add("redirect_uri", redirectUri);
return body;
}
登录演示

原文链接:https://blog.dengwei.site/article/spring-boot-oauth2-github-login
本文来自博客园,作者:衣来伸手饭来张口,转载请注明原文链接:https://www.cnblogs.com/autowin/p/20269152

浙公网安备 33010602011771号