GitHub,Gitee,qq 第三方登录配置完整教程

GitHub,Gitee,qq 第三方登录配置完整教程

GitHub 第三方登录配置完整教程

本教程将详细介绍如何在博客系统中集成 GitHub 第三方登录功能,包括 GitHub OAuth App 创建、前后端配置、代码实现等,适合零基础小白学习。

📚 目录

  1. 什么是 GitHub 第三方登录
  2. 创建 GitHub OAuth App
  3. 后端配置
  4. 前端配置
  5. 代码实现详解
  6. 测试登录
  7. 常见问题

什么是 GitHub 第三方登录

GitHub 第三方登录(OAuth 2.0)允许用户使用 GitHub 账号登录你的网站,无需注册新账号。用户点击"GitHub 登录"后,会跳转到 GitHub 授权页面,授权后 GitHub 会回调到你的网站,完成登录。

优势:

  • ✅ 用户无需注册,一键登录
  • ✅ 安全可靠,由 GitHub 管理用户认证
  • ✅ 自动获取用户头像、昵称等信息

创建 GitHub OAuth App

步骤 1:登录 GitHub

访问 GitHub.com,使用你的账号登录(如果没有账号,先注册一个)。

步骤 2:进入开发者设置

  1. 点击右上角头像
  2. 点击 Settings(设置)
  3. 左侧菜单滚动到最下面,找到 Developer settings(开发者设置)
  4. 点击进入

步骤 3:创建 OAuth App

  1. 在左侧菜单点击 OAuth Apps(OAuth 应用)
  2. 点击右上角 New OAuth App(新建 OAuth 应用)

步骤 4:填写应用信息

填写以下信息:

字段说明示例
Application name应用名称,会显示给用户我的博客
Homepage URL你的网站首页地址http://ariconline.top
Authorization callback URL回调地址,非常重要http://ariconline.top/oauth/login/github

⚠️ 重要提示:

  • Authorization callback URL 必须填写:http://你的域名/oauth/login/github
  • 这个地址必须和前后端配置的地址完全一致(包括协议 http/https)
  • 本地测试需要使用内网穿透工具(如 ngrok),详见本地测试指南

步骤 5:注册应用

点击 Register application(注册应用)

步骤 6:获取 Client ID 和 Secret

注册成功后,你会看到:

  • Client ID:类似 1decdeff65c4ca8daa07(公开的,可以暴露)
  • Client secrets:点击 Generate a new client secret 生成(只显示一次,务必保存

⚠️ 重要: Client Secret 生成后只显示一次,请立即复制保存。如果丢失,需要重新生成。


后端配置

步骤 1:配置环境变量

blog-springboot 目录下找到 .env 文件(如果没有,复制 .env.example 创建),添加:

# GitHub OAuth 配置OAUTH_GITHUB_CLIENT_ID=你的Client_ID OAUTH_GITHUB_CLIENT_SECRET=你的Client_Secret 

示例:

OAUTH_GITHUB_CLIENT_ID=1decdeff65c4ca8daa07 OAUTH_GITHUB_CLIENT_SECRET=abc123def456ghi789jkl012mno345pqr678stu901 

步骤 2:配置回调地址(可选)

编辑 src/main/resources/application-dev.yml

oauth:github:client-id: ${OAUTH_GITHUB_CLIENT_ID:}client-secret: ${OAUTH_GITHUB_CLIENT_SECRET:}redirect-url: ${OAUTH_GITHUB_REDIRECT:http://ariconline.top/oauth/login/github}access-token-url: https://github.com/login/oauth/access_token user-info-url: https://api.github.com/user 

说明:

  • redirect-url 是回调地址,默认使用环境变量 OAUTH_GITHUB_REDIRECT
  • 如果环境变量未设置,使用默认值 http://ariconline.top/oauth/login/github
  • 本地测试时,可以在 .env 中设置 OAUTH_GITHUB_REDIRECT=https://你的ngrok地址/oauth/login/github

步骤 3:重启后端服务

修改配置后,重启 Spring Boot 后端服务使配置生效。


前端配置

步骤 1:修改配置文件

编辑 blog-vue/shoka-blog/src/assets/js/config.ts

exportdefault{// GitHub 的 Client ID(从 GitHub OAuth App 页面获取)GITHUB_APP_ID:"你的Client_ID",// GitHub 回调地址(必须与 GitHub OAuth App 中填写的完全一致)GITHUB_REDIRECT_URL:"http://ariconline.top/oauth/login/github",// ... 其他配置};

示例:

exportdefault{GITHUB_APP_ID:"123456789",GITHUB_REDIRECT_URL:"http://ariconline.top/oauth/login/github",};

步骤 2:本地测试配置(可选)

如果要在本地测试,编辑 .env.dev

# 使用内网穿透地址(如 ngrok)VITE_OAUTH_REDIRECT_BASE=https://abc123.ngrok-free.app 

然后 config.ts 会自动使用这个地址。


代码实现详解

1. 前端登录按钮

在登录弹窗中,添加 GitHub 登录按钮:

文件:src/components/Dialog/Login.vue

<svg-icon icon-class="github" size="2rem" v-if="showLogin('github')" @click="githubLogin" ></svg-icon> 

点击事件:

constgithubLogin=()=>{// 保存当前路径,登录后跳转回来 user.savePath(route.path);// 关闭登录弹窗 app.setLoginFlag(false);// 跳转到 GitHub 授权页面 window.open("https://github.com/login/oauth/authorize?client_id="+ config.GITHUB_APP_ID+"&redirect_uri="+ config.GITHUB_REDIRECT_URL+"&scope=user","_self");};

流程说明:

  1. 用户点击 GitHub 图标
  2. 保存当前页面路径(登录后跳转回来)
  3. 关闭登录弹窗
  4. 跳转到 GitHub 授权页面,URL 包含:
    • client_id:你的 GitHub Client ID
    • redirect_uri:回调地址
    • scope=user:请求用户信息权限

2. GitHub 授权回调

用户授权后,GitHub 会跳转回你的网站,URL 类似:

http://ariconline.top/oauth/login/github?code=abc123def456... 

路由配置:src/router/routes/index.ts

{ path:"/oauth/login/github",component:()=>import("@/components/Oauth/index.vue"),}

3. 回调处理组件

文件:src/components/Oauth/index.vue

onMounted(()=>{const path = route.path;if(path ==="/oauth/login/github"){handleOauthCallback(githubLogin);}// ...});consthandleOauthCallback=async(loginFn:Function)=>{try{// 1. 从 URL 中获取 codeconst{ data }=awaitloginFn({ code: route.query.code asstring});if(data.flag){// 2. 保存 TokensetToken(data.data);// 3. 获取用户信息await user.GetUserInfo();// 4. 检查邮箱(GitHub 可能不返回邮箱)if(user.email ===""){ window.$message?.warning("请绑定邮箱以便及时收到回复");}else{ window.$message?.success("登录成功");}}else{ window.$message?.error("登录失败");}}catch{ window.$message?.error("登录失败,请重试");}// 5. 跳转回原页面或首页const loginUrl = user.path; router.push(loginUrl && loginUrl !==""? loginUrl :"/");};

流程说明:

  1. 组件挂载时,从 URL 获取 code 参数
  2. 调用 githubLogin API,将 code 发送给后端
  3. 后端返回 Token,前端保存
  4. 获取用户信息
  5. 检查邮箱(GitHub 可能不返回邮箱,需要用户补充)
  6. 跳转回原页面

4. 前端 API 调用

文件:src/api/login/index.ts

/** * GitHub登录 * @param code 第三方code(从 GitHub 回调 URL 中获取) * @returns Token */exportfunctiongithubLogin(data: GitInfo): AxiosPromise<Result<string>>{returnrequest({ url:"/oauth/github", method:"post", data,});}

类型定义:src/api/login/types.ts

exportinterfaceGitInfo{ code:string;// GitHub 返回的授权码}

5. 后端 Controller

文件:src/main/java/com/ican/controller/LoginController.java

@PostMapping("/oauth/github")publicResult<String>githubLogin(@RequestBodyCodeReq data){returnResult.success(loginService.githubLogin(data));}

请求 DTO:src/main/java/com/ican/model/vo/request/CodeReq.java

publicclassCodeReq{privateString code;// GitHub 返回的授权码}

6. 后端 Service

文件:src/main/java/com/ican/service/LoginService.java

@Transactional(rollbackFor =Exception.class)publicStringgithubLogin(CodeReq data){// 调用策略模式处理 GitHub 登录return socialLoginStrategyContext.executeLoginStrategy(data,LoginTypeEnum.GITHUB);}

7. 策略模式实现

系统使用策略模式处理不同平台的登录,GitHub 登录策略:

文件:src/main/java/com/ican/strategy/impl/GithubLoginStrategyImpl.java

@Service("githubLoginStrategyImpl")publicclassGithubLoginStrategyImplextendsAbstractLoginStrategyImpl{@AutowiredprivateGithubProperties githubProperties;// 配置属性@AutowiredprivateRestTemplate restTemplate;// HTTP 请求工具/** * 第一步:用 code 换取 access_token */@OverridepublicSocialTokenDTOgetSocialToken(CodeReq codeReq){TokenDTO githubToken =getGithubToken(codeReq.getCode());returnSocialTokenDTO.builder().accessToken(githubToken.getAccess_token()).loginType(LoginTypeEnum.GITHUB.getLoginType()).build();}/** * 第二步:用 access_token 获取用户信息 */@OverridepublicSocialUserInfoDTOgetSocialUserInfo(SocialTokenDTO socialToken){// 设置请求头:Authorization: Bearer {access_token}HttpHeaders headers =newHttpHeaders(); headers.set("Authorization","Bearer "+ socialToken.getAccessToken());HttpEntity<Map<String,String>> requestEntity =newHttpEntity<>(null, headers);// 调用 GitHub API 获取用户信息GitUserInfoDTO gitUserInfoDTO = restTemplate.exchange( githubProperties.getUserInfoUrl(),// https://api.github.com/userHttpMethod.GET, requestEntity,GitUserInfoDTO.class).getBody();// 返回用户信息returnSocialUserInfoDTO.builder().avatar(gitUserInfoDTO.getAvatar_url())// 头像.id(gitUserInfoDTO.getId())// GitHub 用户 ID.nickname(gitUserInfoDTO.getLogin())// GitHub 用户名.build();}/** * 用 code 换取 access_token 的详细实现 */privateTokenDTOgetGithubToken(String code){// 构建请求参数MultiValueMap<String,String> githubData =newLinkedMultiValueMap<>(); githubData.add("client_id", githubProperties.getClientId()); githubData.add("client_secret", githubProperties.getClientSecret()); githubData.add("redirect_uri", githubProperties.getRedirectUrl()); githubData.add("code", code);// 设置请求头:Accept: application/jsonHttpHeaders headers =newHttpHeaders(); headers.setAccept(List.of(MediaType.APPLICATION_JSON));HttpEntity<MultiValueMap<String,String>> requestEntity =newHttpEntity<>(githubData, headers);try{// 发送 POST 请求到 GitHubreturn restTemplate.exchange( githubProperties.getAccessTokenUrl(),// https://github.com/login/oauth/access_tokenHttpMethod.POST, requestEntity,TokenDTO.class).getBody();}catch(Exception e){thrownewServiceException("Github登录错误");}}}

8. 抽象登录模板

文件:src/main/java/com/ican/strategy/impl/AbstractLoginStrategyImpl.java

@OverridepublicStringlogin(CodeReq data){User user;// 1. 获取 GitHub TokenSocialTokenDTO socialToken =getSocialToken(data);// 2. 获取 GitHub 用户信息SocialUserInfoDTO socialUserInfoDTO =getSocialUserInfo(socialToken);// 3. 查找用户是否已注册User existUser = userMapper.selectOne(newLambdaQueryWrapper<User>().eq(User::getUsername, socialUserInfoDTO.getId()).eq(User::getLoginType, socialToken.getLoginType()));// 4. 如果用户不存在,创建新用户if(Objects.isNull(existUser)){ user =saveLoginUser(socialToken, socialUserInfoDTO);}else{ user = existUser;}// 5. 检查账号是否被封禁StpUtil.checkDisable(user.getId());// 6. 使用 Sa-Token 登录,返回 TokenStpUtil.login(user.getId());returnStpUtil.getTokenValue();}

完整流程:

  1. code 换取 access_token
  2. access_token 获取用户信息(头像、ID、用户名)
  3. 查找数据库中是否存在该用户(通过 GitHub ID 和登录类型)
  4. 如果不存在,创建新用户并分配普通用户角色
  5. 检查账号是否被封禁
  6. 使用 Sa-Token 登录,返回 Token 给前端

测试登录

1. 确保配置正确

检查三处地址是否完全一致:

  • ✅ GitHub OAuth App 的回调地址
  • ✅ 前端 config.tsGITHUB_REDIRECT_URL
  • ✅ 后端 .envapplication-dev.ymlredirect-url

2. 启动服务

# 启动后端cd blog-springboot mvn spring-boot:run # 启动前端cd blog-vue/shoka-blog npm run dev 

3. 测试登录

  1. 访问网站首页
  2. 点击右上角"登录"
  3. 点击 GitHub 图标
  4. 跳转到 GitHub 授权页面
  5. 点击 Authorize(授权)
  6. 自动跳转回网站,完成登录

4. 验证登录

  • ✅ 右上角显示 GitHub 头像
  • ✅ 可以访问"我的代办"等登录用户功能
  • ✅ 个人中心显示 GitHub 信息

常见问题

1. 回调地址不匹配

错误信息:redirect_uri_mismatch

原因: 三处回调地址不一致

解决: 确保以下三处完全一致(包括协议 http/https):

  • GitHub OAuth App 设置
  • 前端 config.ts
  • 后端配置

2. Client Secret 错误

错误信息:bad_verification_code

原因: Client Secret 配置错误或已过期

解决:

  • 检查 .env 文件中的 OAUTH_GITHUB_CLIENT_SECRET 是否正确
  • 如果丢失,在 GitHub OAuth App 页面重新生成

3. 本地测试无法回调

原因: GitHub 无法访问 localhost

解决: 使用内网穿透工具(ngrok、natapp),详见本地测试指南

4. 用户没有邮箱

现象: 登录成功但提示"请绑定邮箱"

原因: GitHub 用户可能没有公开邮箱或未授权邮箱权限

解决:

  • 用户可以在个人中心补充邮箱
  • 或在 GitHub 设置中将邮箱设为公开

5. 登录后跳转错误

原因:user.path 保存的路径不正确

解决: 检查 githubLogin 函数中的 user.savePath(route.path) 是否正确执行


总结

GitHub 第三方登录的实现流程:

用户点击 GitHub 登录 ↓ 跳转到 GitHub 授权页面 ↓ 用户授权,GitHub 回调到 /oauth/login/github?code=xxx ↓ 前端发送 code 到后端 POST /oauth/github ↓ 后端用 code 换 access_token ↓ 后端用 access_token 获取用户信息 ↓ 查找或创建用户,Sa-Token 登录 ↓ 返回 Token 给前端 ↓ 前端保存 Token,获取用户信息,跳转回原页面 

关键点:

  1. ✅ 三处回调地址必须完全一致
  2. ✅ Client ID 和 Secret 配置正确
  3. ✅ 本地测试需要使用内网穿透
  4. ✅ 代码已经实现,只需配置即可使用

祝你配置顺利! 🎉

Read more

Flutter 三方库 linalg 的鸿蒙化适配指南 - 掌控高性能线性代数、矩阵运算实战、鸿蒙级算法中枢

Flutter 三方库 linalg 的鸿蒙化适配指南 - 掌控高性能线性代数、矩阵运算实战、鸿蒙级算法中枢

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 linalg 的鸿蒙化适配指南 - 掌控高性能线性代数、矩阵运算实战、鸿蒙级算法中枢 在鸿蒙跨平台应用处理 3D 图形变换、复杂的信号处理(DSP)或是端侧的小型机器学习模型时,高效的矩阵(Matrix)与向量(Vector)运算是一切算法的基石。如果你不想手写枯燥且易错的嵌套循环。今天我们要深度解析的 linalg——一个纯 Dart 实现的、遵循线性代数标准的专业级数学库,正是帮你搭建“算法堡垒”的数字基石。 前言 linalg 提供了一套直观且功能完备的线性代数 API。它不仅支持基础的向量加减、点积(Dot Product)和叉积(Cross Product),还涵盖了复杂的矩阵乘法、转置(Transpose)以及行列式计算。在鸿蒙端项目中,

By Ne0inhk
Flutter for OpenHarmony:Flutter 三方库 os_detect — 精准洞察鸿蒙系统的底层脉络(适配鸿蒙 HarmonyOS Next ohos)

Flutter for OpenHarmony:Flutter 三方库 os_detect — 精准洞察鸿蒙系统的底层脉络(适配鸿蒙 HarmonyOS Next ohos)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net。 Flutter for OpenHarmony:Flutter 三方库 os_detect — 精准洞察鸿蒙系统的底层脉络(适配鸿蒙 HarmonyOS Next ohos) 在进行 Flutter for OpenHarmony 跨平台开发时,我们经常需要处理“差异化”的需求。有的功能可能只在真正的 OpenHarmony 原生环境下运行(如特定的 N-API 调用),而在 Web 或其他桌面模拟器环境下则需要进行降级处理。 传统的 Platform.isAndroid 或 kIsWeb 在处理日渐复杂的鸿蒙生态环境时,往往显得力不从心。os_detect 库提供了一套更轻量、更可靠的系统环境感知方案,能帮助我们精准识别应用正跑在哪个“灵魂”之下。 一、为什么需要系统环境检测?

By Ne0inhk

HarmonyOS 相机开发从入门到放弃

一、背景引入:这玩意儿是干啥的? 今儿个咱聊聊 Camera Kit,中文名儿叫"相机服务"。听名字就知道,这玩意儿就是让你调用相机的。 你可能会问:“调用相机?我自己写个相机应用不就完了吗?” 嘿,您要真这么想,那我得给您点个赞——有这股劲儿,当年我写相机也是这么想的。但踩了几个坑之后,我就服了。 为啥要用 Camera Kit? 咱说个实际场景: 你在应用里想做个拍照功能,用户点了个"拍照"按钮,你得让人家能预览、能拍照、能录像吧?这时候你有几个选择: 1. 自己写底层驱动:跟硬件打交道,ISP、HDI、缓存队列…您慢慢写,写完了叫我一声 2. 用系统相机:拉起系统相机拍一张,简单,但定制性差 3.

By Ne0inhk
Flutter 三方库 klizma 的鸿蒙化适配指南 - 掌握极简的网络请求拦截与调试监控技术、助力鸿蒙应用构建透明且高效的端侧流量审计体系

Flutter 三方库 klizma 的鸿蒙化适配指南 - 掌握极简的网络请求拦截与调试监控技术、助力鸿蒙应用构建透明且高效的端侧流量审计体系

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 klizma 的鸿蒙化适配指南 - 掌握极简的网络请求拦截与调试监控技术、助力鸿蒙应用构建透明且高效的端侧流量审计体系 前言 在 OpenHarmony 鸿蒙应用应对复杂的后端交互、接口联调及性能优化时,网络请求(HTTP Requests)往往是“黑盒逻辑”的高发区。如何在没有外部代理工具(如 Charles/Fiddler)的情况下,直接在鸿蒙手机上实时查看请求 Body、Header 以及响应状态码?如何在开发阶段快速模拟弱网加载或接口报错?klizma 作为一个轻量级、UI 友好的 HTTP 拦截器库,旨在为鸿蒙开发者提供一支“端侧网络放大镜”。本文将详述其在鸿蒙端的实战技法。 一、原原理分析 / 概念介绍 1.1 基础原理 klizma 的核心逻辑是

By Ne0inhk