行业资讯
📅 2026/7/24 4:50:59
Java 实现企业微信扫码登录
Java 实现企业微信扫码登录引言企业微信扫码登录是目前企业应用中常见的身份认证方式尤其适合企业内部的Web管理系统。用户通过企业微信App扫描二维码即可完成登录无需输入账号密码提升了用户体验和安全性。本文将从原理出发结合Java代码示例逐步实现企业微信扫码登录功能。## 企业微信扫码登录原理企业微信扫码登录基于OAuth2.0协议主要流程如下1.生成二维码后端生成一个包含临时授权码code的URL前端将其渲染为二维码。2.用户扫码用户使用企业微信扫描二维码确认登录请求。3.回调通知企业微信服务器将授权码通过回调地址发送给后端。4.获取用户信息后端使用授权码、企业ID、应用Secret等参数调用企业微信API获取用户的access_token和userid。5.完成登录根据userid查询用户信息生成Session或JWT令牌完成登录。## 准备工作### 1. 注册企业微信应用- 登录企业微信管理后台创建自建应用获取CorpID和Secret。- 配置应用的“网页授权及JS-SDK”域名以及“回调域名”。### 2. 依赖引入使用Spring Boot作为框架引入以下依赖xmldependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId/dependencydependency groupIdcom.squareup.okhttp3/groupId artifactIdokhttp/artifactId version4.9.3/version/dependency## 核心实现步骤### 1. 生成二维码URL扫码登录需要提供一个指向企业微信授权页的URL示例代码如下javaimport org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.GetMapping;Controllerpublic class LoginController { Value(${wechat.corpId}) private String corpId; Value(${wechat.redirectUri}) private String redirectUri; GetMapping(/login) public String login(Model model) { // 构造授权URL注意需要URL编码 String authorizeUrl https://open.work.weixin.qq.com/wwopen/sso/qrConnect? appid corpId agentid1000002 // 需要替换为你的应用AgentId redirect_uri java.net.URLEncoder.encode(redirectUri) statestate; model.addAttribute(qrCodeUrl, authorizeUrl); return login; // 返回模板页面 }}前端页面login.html可使用img标签或第三方库如qrcode.js生成二维码html!DOCTYPE htmlhtmlbody h2企业微信扫码登录/h2 img th:src${qrCodeUrl} alt扫码登录二维码 //body/html### 2. 回调处理与获取用户信息用户扫码后企业微信会回调redirect_uri携带code和state参数。后端需处理回调获取用户信息javaimport okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpSession;RestControllerpublic class CallbackController { Value(${wechat.corpId}) private String corpId; Value(${wechat.secret}) private String secret; private final OkHttpClient client new OkHttpClient(); private final ObjectMapper mapper new ObjectMapper(); GetMapping(/callback) public String callback(RequestParam(code) String code, RequestParam(state) String state, HttpSession session) throws Exception { // 1. 获取access_token String tokenUrl https://qyapi.weixin.qq.com/cgi-bin/gettoken? corpid corpId corpsecret secret; Request tokenRequest new Request.Builder().url(tokenUrl).get().build(); Response tokenResponse client.newCall(tokenRequest).execute(); JsonNode tokenJson mapper.readTree(tokenResponse.body().string()); String accessToken tokenJson.get(access_token).asText(); // 2. 通过code获取用户userid String userInfoUrl https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo? access_token accessToken code code; Request userRequest new Request.Builder().url(userInfoUrl).get().build(); Response userResponse client.newCall(userRequest).execute(); JsonNode userJson mapper.readTree(userResponse.body().string()); String userId userJson.get(UserId).asText(); // 注意企业微信返回的是UserId不是OpenId // 3. 模拟登录将userId存入Session session.setAttribute(userId, userId); return 登录成功用户ID: userId; }}## 深入原理分析### OAuth2.0授权码模式上述流程本质上是OAuth2.0的授权码模式-资源所有者企业微信用户-客户端我们的Web应用-授权服务器企业微信服务器-资源服务器企业微信用户信息API关键点在于-code是一次性的有效期很短约5分钟防止重放攻击。-state参数用于防止CSRF攻击后端需验证state值是否与发起请求时的一致。-access_token是企业微信服务器颁发的临时令牌用于调用后续API。### 安全性考虑1.Secret保护CorpSecret是敏感信息应存储在配置中心或环境变量避免硬编码。2.HTTPS请求所有与企业微信的通信必须使用HTTPS。3.Session管理用户登录后应使用安全的Session或JWT并设置过期时间。## 完整代码示例含异常处理以下是一个更完整的回调处理示例包含异常处理和日志记录javaimport org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpSession;import java.io.IOException;RestControllerpublic class WeChatLoginService { private static final Logger log LoggerFactory.getLogger(WeChatLoginService.class); Value(${wechat.corpId}) private String corpId; Value(${wechat.secret}) private String secret; GetMapping(/auth/callback) public String handleCallback(RequestParam(code) String code, RequestParam(state) String state, HttpSession session) { try { // 验证state实际项目中应检查与session中存储的state是否一致 if (!state.equals(state)) { return state校验失败可能存在CSRF攻击; } // 获取access_token String accessToken getAccessToken(); if (accessToken null) { return 获取access_token失败; } // 通过code获取用户信息 String userId getUserId(accessToken, code); if (userId null) { return 获取用户信息失败; } // 登录成功存储用户信息 session.setAttribute(userId, userId); log.info(用户 {} 通过扫码登录成功, userId); return 登录成功欢迎 userId; } catch (Exception e) { log.error(回调处理异常, e); return 登录失败请重试; } } private String getAccessToken() throws IOException { String url String.format(https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid%scorpsecret%s, corpId, secret); Request request new Request.Builder().url(url).get().build(); Response response new OkHttpClient().newCall(request).execute(); JsonNode json new ObjectMapper().readTree(response.body().string()); if (json.has(errcode) json.get(errcode).asInt() ! 0) { log.error(获取access_token失败: {}, json); return null; } return json.get(access_token).asText(); } private String getUserId(String accessToken, String code) throws IOException { String url String.format(https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token%scode%s, accessToken, code); Request request new Request.Builder().url(url).get().build(); Response response new OkHttpClient().newCall(request).execute(); JsonNode json new ObjectMapper().readTree(response.body().string()); if (json.has(errcode) json.get(errcode).asInt() ! 0) { log.error(获取用户信息失败: {}, json); return null; } return json.get(UserId).asText(); }}## 总结本文从原理到代码实现详细介绍了Java实现企业微信扫码登录的完整流程。核心步骤包括生成授权URL、处理回调获取code、通过企业微信API获取access_token和用户信息最终完成登录。实际开发中还需注意配置管理、异常处理、Session安全等细节。扫码登录不仅提升了用户体验也增强了系统安全性是企业级应用的常用认证方式。建议读者结合企业微信官方文档根据实际业务需求进行扩展如绑定已有账号、权限校验等。