【后端新手谈12】四大登录方案

张开发
2026/4/16 19:26:47 15 分钟阅读

分享文章

【后端新手谈12】四大登录方案
登录是 Web/APP 开发的核心功能从传统的Session-Cookie到现代前后端分离的JWT再到便捷的第三方登录不同场景需要适配不同的登录方案。本文将基于 SpringBoot 完整整合Session-Cookie、JWT Token、Basic Auth、OAuth2.0四种核心登录方式并补充登录拦截器、Spring Security 权限控制、Redis 实现 JWT 黑名单踢人功能以及真实对接 GitHub、微信、支付宝第三方登录同时补全所有常见、面试常考、实际项目会用到的登录方式每段内容简洁易懂适合实战参考。一、前置准备环境与依赖配置首先搭建基础项目环境明确依赖包作用确保所有功能正常运行。本文采用 JDK 8、SpringBoot 2.7.x无需数据库全部模拟登录逻辑核心依赖如下1.1 完整 pom.xml 依赖解释dependencies !-- 基础 Web 依赖提供 Servlet、Controller 等核心功能 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Spring Security 依赖用于权限控制、登录校验 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-security/artifactId /dependency !-- Redis 依赖用于存储 JWT 黑名单、共享 Session 等 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency !-- JWT 依赖用于生成、解析 Token前后端分离核心 -- dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt-api/artifactId version0.9.1/version /dependency dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt-impl/artifactId version0.9.1/version scoperuntime/scope !-- 运行时依赖无需编译时引入 -- /dependency dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt-jackson/artifactId version0.9.1/version scoperuntime/scope /dependency !-- OAuth2 第三方登录依赖自动集成 GitHub、Google 等第三方登录 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-oauth2-client/artifactId /dependency !-- Hutool 工具类简化 HTTP 请求、加密等操作第三方登录必备 -- dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.20/version /dependency /dependencies1.2 application.yml 配置解释spring: redis: host: localhost # Redis 服务器地址本地测试用 localhost port: 6379 # Redis 默认端口 # 若 Redis 有密码添加 password: 你的密码 security: oauth2: client: registration: github: client-id: 你的GitHub ClientID # 自己在 GitHub 开发者平台申请 client-secret: 你的GitHub ClientSecret # 对应 ClientID 的密钥 scope: login,user:email # 申请的权限获取用户登录信息、邮箱说明Redis 用于存储 JWT 黑名单实现踢人、强制下线功能本地需启动 Redis 服务GitHub ClientID 和 ClientSecret 需要在 GitHub 开发者平台申请具体申请流程可参考文末补充说明。二、核心工具类JWT Redis 黑名单关键增强JWT 是前后端分离的核心登录方案但默认无法主动作废 Token结合 Redis 存储黑名单可实现“踢人”“强制下线”功能以下是完整工具类及详细解释import io.jsonwebtoken.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import java.util.Date; import java.util.concurrent.TimeUnit; Component // 交给 Spring 管理方便其他类注入使用 public class JwtUtil { Autowired private StringRedisTemplate redisTemplate; // 注入 Redis 操作模板 // JWT 加密密钥自定义建议复杂一些防止破解 private static final String SECRET mySecretKey1234567890abcdef; // Token 有效期这里设置为 24 小时可根据需求调整 private static final long EXPIRE 1000 * 60 * 60 * 24; // 生成 Token根据用户名生成包含用户身份信息加密存储 public String createToken(String username) { return Jwts.builder() .setSubject(username) // 设置 Token 主题存储用户名用于后续解析 .setExpiration(new Date(System.currentTimeMillis() EXPIRE)) // 设置过期时间 .signWith(SignatureAlgorithm.HS512, SECRET) // 采用 HS512 算法加密指定密钥 .compact(); // 生成最终的 Token 字符串 } // 解析 Token从 Token 中获取用户名验证 Token 有效性 public String getUsername(String token) { try { return Jwts.parser() .setSigningKey(SECRET) // 使用相同密钥解析 .parseClaimsJws(token) // 解析 Token获取声明包含主题、过期时间等 .getBody() // 获取 Token 体内容 .getSubject(); // 取出用户名 } catch (Exception e) { // 捕获 Token 过期、签名错误等异常返回 null 表示 Token 无效 return null; } } // 判断 Token 是否在黑名单退出登录、被踢后Token 会被加入黑名单 public boolean isBlack(String token) { // Redis 中存储黑名单的 key 格式jwt:black:token值判断该 key 是否存在 return Boolean.TRUE.equals(redisTemplate.hasKey(jwt:black: token)); } // 将 Token 加入黑名单用于退出登录、强制踢人 public void addBlack(String token) { // 存储黑名单有效期设置为 1 天与 Token 有效期一致避免无效数据占用空间 redisTemplate.opsForValue().set(jwt:black: token, token, 1, TimeUnit.DAYS); } }核心逻辑生成 Token 时加密存储用户名和过期时间解析 Token 时验证有效性退出/踢人时将 Token 加入 Redis 黑名单拦截器会校验 Token 是否在黑名单中从而拒绝无效请求。三、常见登录方式以下涵盖所有常见登录方式按实现逻辑分类简洁介绍核心原理、适用场景既包含前文详细实现的4种也补充14种高频登录方式兼顾入门理解和面试备考。3.1 基础核心登录方式Session Cookie 登录传统 Web 标配后端存 Session用户状态前端存 SessionIDCookie浏览器自动携带适合传统非前后端分离项目。import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpSession; RestController // 标识为接口控制器返回 JSON 数据 RequestMapping(/session) // 所有接口统一前缀 /session public class SessionLoginController { // 登录接口接收用户名密码验证通过后创建 Session PostMapping(/login) public String login(String username, String password, HttpSession session) { // 模拟账号密码校验真实项目中需查询数据库 if (admin.equals(username) 123456.equals(password)) { // 校验通过将用户名存入 SessionSession 存储在服务器端 session.setAttribute(user, username); // 返回 SessionID方便测试浏览器会自动将 SessionID 存入 Cookie return Session 登录成功 session.getId(); } return 账号或密码错误; } // 获取当前登录用户通过 Session 校验是否登录 GetMapping(/user) public String user(HttpSession session) { // 从 Session 中获取用户信息若为 null 表示未登录 Object user session.getAttribute(user); return user null ? 未登录 : 当前用户 user; } // 退出登录销毁 Session清除用户状态 GetMapping(/logout) public String logout(HttpSession session) { // invalidate() 方法会销毁当前 Session清除所有属性 session.invalidate(); return 退出成功; } }JWT Token 登录前后端分离标配后端无状态Token 加密存储用户信息前端手动携带适合 Vue/React 项目、APP、小程序。import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; RestController RequestMapping(/jwt) // 接口统一前缀 /jwt public class JwtLoginController { Autowired private JwtUtil jwtUtil; // 注入 JWT 工具类 // 登录接口验证通过后生成 Token 并返回 PostMapping(/login) public String login(String username, String password) { // 模拟账号密码校验 if (admin.equals(username) 123456.equals(password)) { // 生成 Token 并返回前端需存储该 Token后续请求携带 return jwtUtil.createToken(username); } return 登录失败; } // 获取当前登录用户校验请求头中的 Token GetMapping(/user) public String user(RequestHeader(Authorization) String token) { // 解析 Token获取用户名 String username jwtUtil.getUsername(token); // 若用户名为 null说明 Token 无效或已过期 return username null ? token 无效或已过期 : JWT 用户 username; } }Basic Auth 登录极简基础认证账号密码 Base64 编码放入请求头仅适合测试环境、临时接口安全性低。import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Base64; RestController RequestMapping(/basic) // 接口统一前缀 /basic public class BasicAuthController { // 认证接口校验请求头中的 Basic Auth 信息 GetMapping(/user) public String user(RequestHeader(Authorization) String auth) { // 校验请求头格式必须以 Basic 开头浏览器原生弹框登录会自动拼接 if (auth null || !auth.startsWith(Basic )) { return 请使用 Basic Auth 认证; } // 截取 Base64 编码部分去掉前面的 Basic String base64 auth.substring(6); // 解码 Base64得到 用户名:密码 格式的字符串 String decode new String(Base64.getDecoder().decode(base64)); // 分割用户名和密码 String[] up decode.split(:); // 校验账号密码模拟 if (up.length 2 admin.equals(up[0]) 123456.equals(up[1])) { return Basic Auth 认证通过 up[0]; } return 认证失败; } }OAuth2.0 第三方登录委托第三方平台GitHub、微信、支付宝认证无需自己校验密码适合面向 C 端产品。GitHub 登录自动集成可直接使用Spring Security OAuth2 已封装好 GitHub 登录逻辑只需在 application.yml 配置 ClientID 和 ClientSecret无需额外编写大量代码。import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; RestController public class GitHubLoginController { // 登录成功后获取用户信息GitHub 会返回昵称、头像、邮箱等信息 GetMapping(/github/user) public OAuth2User githubUser(Authentication authentication) { // 从 Authentication 中获取第三方用户信息OAuth2User 包含所有返回的用户数据 return (OAuth2User) authentication.getPrincipal(); } }使用方法启动项目后访问 /oauth2/authorization/github自动跳转到 GitHub 授权页登录 GitHub 并同意授权后会自动跳转回项目访问 /github/user 即可获取 GitHub 用户信息微信登录真实对接官方接口微信登录需先在微信开放平台申请 APPID 和 APPSECRET核心流程前端跳转微信授权页 → 获取 code → 用 code 换取 access_token → 用 access_token 获取用户信息。import cn.hutool.http.HttpUtil; 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; RestController RequestMapping(/wx) // 接口统一前缀 /wx public class WxLoginController { // 微信登录回调接口前端跳转微信授权页后微信会回调该接口并携带 code GetMapping(/callback) public String callback(RequestParam String code) { // 1. 用 code 换取 access_token微信官方接口 String url https://api.weixin.qq.com/sns/oauth2/access_token ?appid你的APPID // 替换为自己的微信 APPID secret你的APPSECRET // 替换为自己的微信 APPSECRET code code // 微信回调返回的 code grant_typeauthorization_code; // 固定值 // 发送 HTTP GET 请求获取微信返回的结果包含 access_token、openid 等 String res HttpUtil.get(url); // 2. 后续可通过 access_token 和 openid 获取用户昵称、头像等信息按需扩展 // 此处简化处理直接返回登录成功信息 return wx login success: res; } }支付宝登录真实对接官方接口支付宝登录需在支付宝开放平台申请应用获取公钥、私钥核心流程前端发起支付宝登录 → 支付宝回调接口 → 验证签名 → 完成登录。import com.alipay.api.AlipaySignature; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Map; RestController RequestMapping(/alipay) // 接口统一前缀 /alipay public class AlipayController { // 支付宝登录回调接口支付宝会以 POST 方式回调该接口携带用户信息和签名 PostMapping(/callback) public String callback(RequestParam MapString, String params) { try { // 验证支付宝签名确保请求来自支付宝防止伪造 // 参数回调参数、支付宝公钥、编码格式、签名算法 boolean ok AlipaySignature.rsaCheckV1( params, 你的支付宝公钥, UTF-8, RSA2 ); if (ok) { // 签名验证通过可从 params 中获取用户信息如支付宝用户 ID return alipay login success; } } catch (Exception e) { e.printStackTrace(); } return fail; } }3.2 补充高频登录方式5. 刷新令牌机制Refresh TokenJWT 升级方案登录返回 access_token短时效 refresh_token长时效access_token 过期后用 refresh_token 换新解决频繁登录问题适合 APP、长期登录场景。6. 单点登录 SSOSingle Sign-On一次登录多系统互通企业后台、中台常用CAS、OAuth2.0、OIDC 均可实现典型如阿里云、腾讯云后台。7. 短信验证码登录主流无密码登录前端输手机号→后端发验证码→验证通过登录本质是 Token/Session 登录适配 APP、移动端网页。8. 邮箱验证码/邮箱链接登录与短信登录逻辑类似分验证码验证和一键登录链接magic link适合PC端、海外产品。9. 双因素认证 2FA/MFA密码二次验证谷歌验证器、短信验证码、硬件UKey安全性高适合金融、后台管理系统。10. 证书登录SSL 证书/数字证书用客户端证书做身份认证无需密码安全性极高多用于银行、政府、企业内网系统。11. 生物识别登录指纹、面容ID、声纹登录本地验证后传给后端 Token适合 APP、移动端设备。12. 扫码登录网页展示二维码手机 App 扫码授权后端推送登录状态基于 OAuth2.0 或自定义长连接微信、QQ、B站均采用。13. 自动登录/记住我Remember Me非独立登录方式通过持久 Cookie 或长期 Token 实现下次访问自动登录提升用户体验。14. 无感登录/免密登录设备绑定、本机特征识别、运营商网关认证一键登录无需用户手动操作适合高频访问场景。15. IP 白名单/内网免登录企业内部系统常用根据 IP 直接放行常配合域账号 AD 域登录使用不对外暴露。16. LDAP/域账号登录企业内部统一身份登录适配 Windows 域环境Jenkins、GitLab、企业后台常用。17. OpenID ConnectOIDCOAuth2.0 的上层标准专门用于登录支持 ID Token比 OAuth2.0 更完整适合第三方安全登录。18. SAML 2.0企业级 SSO 标准比 OAuth2.0 更重、更安全多用于企业 SaaS、教育、政府系统。3.3 登录方式快速记忆汇总传统场景Session-Cookie前后端分离JWT长期稳定登录Refresh Token多系统互通SSO、CAS、SAML、OIDC第三方登录OAuth2.0无密码登录短信、邮箱、扫码、生物识别高安全场景2FA、证书、LDAP四、增强功能登录拦截器 Spring Security 整合单纯的登录接口无法满足实际项目需求需添加统一登录拦截器校验所有请求是否登录、Spring Security 权限控制细粒度权限管理以下是完整实现。4.1 统一登录拦截器全局校验登录状态拦截所有请求校验 Token 是否有效、是否在黑名单未登录或 Token 无效则拒绝访问避免每个接口重复编写校验逻辑。import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; Component // 交给 Spring 管理 public class LoginInterceptor implements HandlerInterceptor { Autowired private JwtUtil jwtUtil; // 注入 JWT 工具类用于校验 Token // 拦截器核心方法请求执行前校验preHandle Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 1. 从请求头中获取 Token String token request.getHeader(Authorization); // 2. 校验 Token 是否存在 if (token null || token.isEmpty()) { response.getWriter().write(no login); // 返回未登录提示 return false; // 拦截请求不继续执行 } // 3. 校验 Token 是否在黑名单已退出/被踢 if (jwtUtil.isBlack(token)) { response.getWriter().write(token expired or kicked); // 返回 Token 无效提示 return false; } // 4. 校验 Token 有效性解析用户名 String username jwtUtil.getUsername(token); if (username null) { response.getWriter().write(invalid token); // 返回 Token 无效提示 return false; } // 所有校验通过放行请求 return true; } }注册拦截器让拦截器生效import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; Configuration // 标识为配置类 public class WebConfig implements WebMvcConfigurer { Autowired private LoginInterceptor loginInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns(/**) // 拦截所有请求 // 排除不需要拦截的接口登录、第三方登录等 .excludePathPatterns(/login, /oauth/**, /security/login, /session/login); } }4.2 Spring Security 整合配置Spring Security 提供完整的权限控制功能整合后可实现登录校验、角色权限管理、第三方登录集成等以下是基础配置适配本文所有登录方式。import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; Configuration EnableWebSecurity // 开启 Spring Security 功能 public class SecurityConfig { Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf().disable() // 关闭 CSRF 防护前后端分离项目常用避免请求被拦截 .authorizeRequests() // 配置请求授权规则 // 允许所有请求访问的接口登录、第三方登录回调等 .antMatchers(/login, /oauth/**, /wx/callback, /alipay/callback).permitAll() // 其他所有请求都需要认证登录后才能访问 .anyRequest().authenticated() .and() // 配置表单登录Spring Security 自带登录页可自定义 .formLogin().loginPage(/security/login) .and() // 开启 OAuth2 第三方登录支持 GitHub 等第三方登录 .oauth2Login(); // 返回 Security 过滤器链生效配置 return http.build(); } }五、补充退出登录与踢人功能实现结合 JWT Redis 黑名单实现退出登录和强制踢人功能核心逻辑是将 Token 加入黑名单拦截器会自动校验并拒绝无效请求。import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; RestController public class LoginController { Autowired private JwtUtil jwtUtil; // 通用登录接口适配 JWT 登录可替换为其他登录方式 PostMapping(/login) public String login(String username, String password) { if (admin.equals(username) 123456.equals(password)) { return jwtUtil.createToken(username); } return error; } // 退出登录将 Token 加入黑名单使其失效 GetMapping(/logout) public String logout(HttpServletRequest request) { String token request.getHeader(Authorization); jwtUtil.addBlack(token); // 加入黑名单 return logged out; } // 强制踢人管理员功能需扩展权限控制 GetMapping(/kick) public String kick(String token) { jwtUtil.addBlack(token); // 将指定 Token 加入黑名单实现踢人 return kick success; } // 获取当前登录用户信息 GetMapping(/me) public String me(HttpServletRequest request) { String token request.getHeader(Authorization); return current user: jwtUtil.getUsername(token); } }六、项目启动类核心入口简单配置启动类无需额外逻辑启动后即可访问所有接口。import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication // 标识为 SpringBoot 应用自动扫描组件 public class LoginApplication { public static void main(String[] args) { // 启动 SpringBoot 项目 SpringApplication.run(LoginApplication.class, args); } }七、总结与补充说明7.1 核心功能汇总本文实现的 SpringBoot 项目包含以下所有功能可直接用于实战开发同时覆盖面试常考登录方式18种常见登录方式含基础核心4种补充14种覆盖传统、现代、高安全、第三方等所有场景增强功能统一登录拦截器、Spring Security 权限控制、Redis JWT 黑名单踢人/退出实操代码完整可运行的 SpringBoot 代码包含核心登录、拦截器、权限配置复制即可启动7.2 注意事项本地测试需启动 Redis 服务否则 JWT 黑名单功能无法使用GitHub、微信、支付宝的 APPID、密钥等需在对应开放平台申请替换代码中的占位符Basic Auth 仅适合测试环境生产环境需使用 JWT 或 OAuth2.0确保安全性Token 有效期、Redis 黑名单有效期可根据实际需求调整高安全场景金融、政府优先选择 2FA、证书登录、LDAP 登录避免使用简单认证方式第三方登录OAuth2.0、OIDC需注意授权范围避免过度获取用户信息7.3 扩展建议可根据实际项目需求扩展以下功能添加 Swagger 接口文档方便接口测试和管理整合数据库实现真实账号密码校验、用户信息存储扩展 Spring Security 角色权限实现细粒度权限控制如管理员、普通用户前端 Vue/React 对接代码实现前端登录、Token 存储、请求拦截补充 Refresh Token、短信验证码登录的完整代码实现贴合项目实操本文登录方式覆盖全面适合新手入门学习、开发者快速集成以及面试备考若有疑问可根据实际场景调整配置和逻辑。

更多文章