☰
微信登录与OAuth2.0原理详解:扫码、小程序到C#后端接入
2026/10/7 4:10:58 网站建设 项目流程

你有没有想过一个很诡异的事情:你打开京东、淘宝、各种App,点一下"微信登录",输入的是微信的密码,或者干脆扫码,京东却知道"你就是你"。更离谱的是,京东自始至终没有拿到你的微信密码,甚至连你的微信号都没看见,它就敢放你进到购物车、订单页、收货地址这些核心数据里。这个问题被身边人问过无数次,我刚入行后端时也好奇过,后来把OAuth2.0和微信开放平台的文档翻透才发现:登录和授权,本来就是两码事。这篇文章就从这个问题出发,把微信登录、扫码登录、小程序登录获取手机号的原理彻底讲透,最后再给一份C#后端接入微信登录验证的完整实现方案。

很多人以为第三方登录是"微信把账号信息直接告诉京东",这是最大的误解。微信公众号、小程序、App登录这套体系,核心协议是OAuth2.0。它解决的核心问题就是:客户端如何在用户不交出密码的前提下,安全地获取用户身份信息。理解这一点,你再看京东的微信登录,就完全不会觉得神奇了。

1. 先说结论:京东压根不需要知道你的微信密码

1.1 登录与授权:两个被混为一谈的动作

传统账号密码登录的逻辑很简单:你注册时给京东一个密码,登录时再把密码提交给京东,京东把你提交的密码和数据库里的哈希值比对,一致就放行。这个模型里,密码只有一个持有方,就是京东,用户和京东之间是"直接信任"关系。

但你的微信账号和密码,是微信体系内的重要凭证。京东如果要"知道你的微信密码",就意味着你必须在京东的页面里输入微信密码,微信完全不知情,整个链条里密码会被京东服务器记录、传输、存储,哪怕京东再小心,只要它收到过你的密码,就存在泄露风险。这显然不能接受。

微信登录换了一套思路:微信作为你的身份提供方,先确认"你是不是你",然后给京东一个受控的凭证,京东用这个凭证去微信换取你的部分公开信息。整个过程里,你不需要向京东透露密码,京东也拿不到密码。这个凭证就是OAuth2.0里的授权码和访问令牌。

用生活里的例子类比:传统密码登录是你把家门钥匙交给超市老板,老板拿着钥匙去你家确认你住这里;微信登录是你小区的门卫大爷替你做担保,他朝超市老板点个头说"这人我认识,是1栋的住户",老板就放你进超市,但门卫不会把钥匙给老板,也不会告诉老板你家有几道锁、保险柜在哪个位置。

1.2 京东到底从微信拿到了什么

通过微信登录,京东通常能拿到的是:微信授权页面里明确公示给你的那些信息,一般包括头像、昵称、性别、地区,以及一个针对京东这个应用唯一的openid。注意,这里的openid不是一个你能直接读懂的微信号,也不是手机号,它是一串类似"oXk8s5j9yG2..."的字母数字,专门给京东用来识别你这个用户。

京东拿不到的是:你的微信号、微信密码、聊天记录、通讯录、朋友圈内容、好友列表。这些信息不在OAuth2.0的授权范围内,微信也不会开放这些数据给第三方应用。

这里有一个很关键的设计:同一个用户在不同应用里的openid是不同的。你在京东的openid是A,在一个叫"某某优惠券"的App里的openid是B,两者完全不一致,这样第三方应用之间没法通过openid串通起来追踪你的全网行为。如果某个开发者同时运营多个应用,想要识别同一个微信用户,必须通过微信开放平台的unionid机制,那是另一个话题,但单就"京东能不能通过微信登录顺藤摸瓜看到你的微信社交关系"这个问题,答案是否定的,协议层面就堵死了。

2. OAuth2.0的设计思路:把验证身份这件事外包出去

2.1 OAuth2.0到底是什么

OAuth2.0不是一个加密算法,也不是一段特定的代码,它是一个授权协议,标准定义在RFC 6749中。它规定了一套角色分工和交互流程,让第三方应用可以在用户本人同意的情况下,受限制地访问用户在另一个平台上托管的资源。

说到OAuth2.0,绕不开四个角色:

角色对应到微信登录场景
资源所有者你,微信用户
客户端京东App或京东网页
授权服务器微信开放平台后台
资源服务器微信保存用户头像、昵称等信息的服务器

整个流程的目标可以浓缩成一句话:让京东(客户端)从微信(授权服务器)拿到一个凭证,再用这个凭证去访问你在微信(资源服务器)上的用户信息。

2.2 为什么要有授权码,而不是直接把令牌扔给京东

OAuth2.0有四种授权模式,微信网页登录采用的是其中安全性最高的"授权码模式"。授权码模式里有一个关键中间品:code。

为什么不能微信直接把access_token通过浏览器重定向返回给京东?因为浏览器太容易泄密了。你想想,access_token一旦发到浏览器端,它就可能出现在历史记录、网络请求日志、浏览器插件能读到的环境里,而且浏览器端根本无法保证这个token会被京东自己拿到还是被别的脚本截获。

授权码模式的设计是:微信先把一个有效期极短、只能用一次的code通过浏览器传给京东,京东拿到code之后,在服务端用这个code配合自己的AppSecret,向微信的后端接口换取access_token。整个换token的过程发生在服务器与服务器之间,浏览器参与不进来,AppSecret也不会暴露给前端。

这里的生活类比是:你去酒店前台,前台给你一张只限当天使用、只能进一次健身房的门卡,而不是直接把房卡打印出来贴在电梯口。你通过正规渠道(前台)换到真正的门卡,而那张临时纸条即使被捡到,也换不了什么东西。

2.3 密码模式为什么在这里行不通

OAuth2.0里其实有一种"密码模式",允许客户端直接拿用户名和密码去授权服务器换token。这种模式设计初衷是给自家开发的第一方应用用的,因为它要求客户端必须可信到能接收用户密码。

第三方登录如果走密码模式,那就完全违背初衷了。你让用户在京东页面上输入微信的账号密码,京东就成了微信密码的经手方,所有安全设计全部失效。这也是为什么微信开放平台从来没有把"微信公众号登录"做成密码模式的原因之一。微信登录用的授权码模式,本质上就是微信对外说:你可以信任我,但我不把底牌交给你。

3. 微信网页登录完整链路拆解:从点击到回跳

3.1 点下"微信登录"后,后台发生了什么

先说微信开放平台网站应用的扫码登录。整个流程从用户点击按钮那一刻开始,就变成了一串HTTP请求和重定向。

第一步,京东的后端需要生成一个授权链接,大概长这样:

https://open.weixin.qq.com/connect/qrconnect?appid=wx1234567890abcdef&redirect_uri=https%3A%2F%2Fwww.jd.com%2Fapi%2Fwechat%2Fcallback&response_type=code&scope=snsapi_login&state=abc123xyz#wechat_redirect

这个链接里的参数很关键,拆开看:

  • appid:京东在微信开放平台申请到的应用唯一标识。
  • redirect_uri:微信确认用户身份之后,把用户浏览器重定向回京东的回调地址,必须URL编码。
  • response_type=code:告诉微信,京东要的是授权码。
  • scope=snsapi_login:授权范围,这里表示网页登录场景。
  • state:京东自己生成的随机字符串,防止CSRF攻击,后面细说。

第二步,用户访问这个链接后,微信服务器会展示一个二维码页面。你用手机微信扫码,手机上会弹出确认授权页,列出京东准备获取的权限:头像、昵称、性别、地区等。

第三步,你点确认授权后,微信后台会把浏览器重定向回京东回调地址,并且在URL上附带两个参数:

https://www.jd.com/api/wechat/callback?code=o6ZGv9X3bN9mQFt0&state=abc123xyz

注意,此时京东只拿到了一个code和一个state。

第四步,京东后端收到请求后,先用state验证请求是自己发起的,再用code去微信后端换取access_token。换取的接口是:

GET https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code

这一步务必放在服务端执行,因为请求里带了AppSecret,AppSecret一旦泄露进浏览器,等同于把微信应用的管理权限拱手让人。

第五步,京东用返回的access_token和openid调用用户信息接口:

GET https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

然后拿到昵称、头像、性别、城市等公开信息。

第六步,京东拿openid去自己的数据库里查有没有绑定记录,没有就创建一个新用户,有就直接登录,然后给用户签发京东自己的登录态,比如Session或JWT。从此以后,用户再访问京东时,走的全是京东自己的会话体系,不需要再经过微信。

3.2 state参数是白拿的吗?为什么必须校验

很多粗心的开发者拿到回调地址,一看有code就赶紧去换token,完全忽略state。这非常危险。

state的设计意图是:让发起授权的客户端判断"这个回调是不是我自己发起的流程"。它应该是一个随机字符串,在生成授权链接时由后端生成,存入Session或Redis,用户被重定向回来时后端取出state对比,不一致就拒绝后续流程。

如果不校验state,攻击者可以构造这样一个场景:他诱导你在他的网站上点一个授权链接,这个链接的redirect_uri是京东的回调地址,你会被带到一个微信授权页,你一旦点击同意,微信就会把code发到京东的回调地址。此时京东后端如果能把这个code和攻击者控制的账号关联起来,那攻击者的账号就绑定了你的微信身份,你后续在京东上的数据可能会被攻击者看到。这种攻击叫登录CSRF,本质上是"借你的授权,绑他的账号"。

所以state不是可有可无,它是一道必须认真对待的安全防线。实际项目中我是用Guid随机生成,设置5到10分钟过期,换token之前先校验。

3.3 为什么code用一次就作废

code是一次性的,这一点在微信官方文档里写得很明确。换取access_token成功之后,同一个code再次使用,微信会返回类似"invalid code"的错误。

业务上这是为了防止重放攻击。code在URL里传输,如果被中间人截获,一旦它能重复使用,攻击者就可以拿着这个code去冒充用户换token。设成一次性之后,截获的价值远低于有效期内成功截获并立即使用的难度,攻击窗口被压缩到几分钟甚至更短。

还有一个容易被忽略的细节:code会在日志里留痕。很多团队为了方便排查问题,把回调URL上的所有参数都打进了日志,code就被记录下来了。我后来在日志系统里加了URL参数脱敏,code、token一律打码,没必要因为排查问题给安全埋雷。

4. 微信生态里的三个登录变种:扫码、App内授权、小程序

4.1 网页扫码登录和App内微信登录的差别

网页端微信登录走的是snapi_login,用户看到二维码,用手机扫描确认。App内微信登录走的是微信SDK的授权流程,用户在App里点"微信登录",系统调起微信App,用户在微信里确认授权,然后通过App间跳转把code传回你的App。

这两种方式底层都是同一个OAuth2.0授权码模式,区别只在"怎么调起授权"和"怎么把code传回来"。如果做C#后端,前端的事情对你来说是透明的,你只需要等前端把code传到后端即可。要注意的是移动端App接入微信SDK时,需要在微信开放平台创建"移动应用",并且做应用签名校验,这和网站应用的流程是分开审核的。

4.2 小程序登录:wx.login拿到code,后端换session_key

小程序里的登录体验不太一样。你打开一个小程序,它默认会静默地调用wx.login,拿到一个临时code,然后把code传给后端。后端再调用微信的jscode2session接口换取openid和session_key。

GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=CODE&grant_type=authorization_code

这里有个重要差异:网页登录换来的是access_token,小程序登录换来的是session_key。session_key的用途是解密小程序端加密数据,比如老版本获取手机号时需要用它解密,这个密钥绝对不能返回给前端。同时,session_key的有效期是不确定的,用户如果频繁调wx.login,旧的session_key可能会失效,后端要能容忍这种情况。

小程序"登录"和网页授权码模式还有个体验上的不同:很多小程序里用户打开就登录了,没有显式的授权页。这是因为小程序本身在微信生态内,微信已经把用户登录状态通过code传递给你,你不需要再让用户点一次"确认授权"。但获取用户头像昵称、手机号这类敏感信息时,仍然需要用户主动授权。

4.3 小程序获取手机号:新旧两种方式怎么选

小程序里获取手机号是常见需求,因为手机号可以直接关联真实身份和做风控。以前的做法是:页面放一个button,设置open-type="getPhoneNumber",用户点击后,前端会拿到encryptedData和iv,连同一个code一起交给后端,后端用session_key做AES解密取出手机号。

这个方案不是不能用,但加解密细节很多,网上教程里key和iv的取法版本五花八门,非常容易踩坑。现在微信官方已经推荐了新方案:利用getPhoneNumber返回的code,后端直接调用官方接口拿手机号,全程不需要自己解密。

新方案流程:

  1. 前端按钮open-type="getPhoneNumber"触发,用户授权后拿到code。
  2. 前端把code传给后端。
  3. 后端拿到access_token(这里的access_token是接口调用凭据,不是用户token),请求:POST https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=ACCESS_TOKEN请求体里带上{"code": "前端传来的code"}。
  4. 接口直接返回用户的手机号信息。

这个新方案大大降低了开发门槛,也避免了session_key解密过程中因为版本差异导致的兼容性问题。我现在的项目里,如果只要求拿手机号,一律走新接口;只有需要获取其他加密数据时才考虑老方案,而且会严格封装解密工具类,避免到处复制粘贴。

4.4 unionid:多应用识别同一用户的钥匙

微信生态里还有一个概念必须提:unionid。同一微信用户,在公众号、小程序、App、网站应用里的openid都不一样,如果你运营多个应用,想判断"这是同一个用户",就需要借助unionid。

要拿到unionid,前提是这些应用都绑定在同一个微信开放平台账号下,并且用户同时授权过这些应用。C#后端在处理登录时,判断逻辑通常是:先查openid,再查unionid,都没有就新建账号。很多电商平台多端打通的帐号体系就是靠unionid实现的。不过京东这种体量的平台,一般会引导用户绑定手机号来统一跨端身份,unionid只是辅助手段。

5. C#后端实现微信登录验证:一份能跑的代码

5.1 开发前准备:AppID、AppSecret、回调地址

动手写代码之前,先到微信开放平台注册账号,创建"网站应用",拿到两样东西:AppID和AppSecret。AppID相当于应用的身份证号,可以出现在前端;AppSecret相当于应用的管理员密码,只能保存在后端服务器、配置文件或密钥管理服务里,绝不能放进前端代码或Git仓库。

同时要在开放平台配置"授权回调域"。网站的授权回调域通常填你的域名,比如https://www.example.com。注意,很多开发者最后报错redirect_uri参数错误,就是后台配置的域名和授权链接里redirect_uri的域名不一致,差一个端口、一个http/https都过不了。

本地开发时,通常需要把本地服务映射到外网才能收到微信的异步回调,因为微信服务器无法访问你的localhost。我用.NET开发时,常用.NET Aspire自带的内网穿透,或者用一些内网穿透工具把本地端口映射成一个HTTPS域名,然后把授权回调域临时改成这个域名,才能走完整流程。

5.2 第一步:生成授权链接并保存state

在ASP.NET Core里,后端要提供一个接口生成授权链接。模型中存储state时,我用一个小类:

public class OAuthState { public string State { get; set; } public DateTime ExpireAt { get; set; } }

生成链接的逻辑很简单:

public IActionResult StartWechatLogin() { var state = Convert.ToBase64String(Guid.NewGuid().ToByteArray()) .TrimEnd('=').Replace('+', '-').Replace('/', '_'); var redirectUri = Url.Action("WechatCallback", "Auth", null, Request.Scheme); var encodedRedirectUri = Uri.EscapeDataString(redirectUri); var url = $"https://open.weixin.qq.com/connect/qrconnect?appid={_wechatConfig.AppId}&redirect_uri={encodedRedirectUri}&response_type=code&scope=snsapi_login&state={state}#wechat_redirect"; HttpContext.Session.SetString("wechat_oauth_state", state); return Redirect(url); }

这里的redirect_uri必须用ASP.NET Core根据请求生成,保证域名和实际被打到的地址一致,否则又是redirect_uri参数错误。

5.3 第二步:回调接口处理code并换token

用户扫码同意后,微信会带着code和state回到你的回调地址。此时后端要做的第一件事不是换token,而是校验state:

public async Task<IActionResult> WechatCallback(string code, string state) { var expectedState = HttpContext.Session.GetString("wechat_oauth_state"); if (string.IsNullOrEmpty(expectedState) || state != expectedState) { return BadRequest("state校验失败"); } var client = _httpClientFactory.CreateClient(); var tokenUrl = $"https://api.weixin.qq.com/sns/oauth2/access_token?appid={_wechatConfig.AppId}&secret={_wechatConfig.AppSecret}&code={code}&grant_type=authorization_code"; var tokenResponse = await client.GetFromJsonAsync<WechatTokenResponse>(tokenUrl); if (tokenResponse == null || !string.IsNullOrEmpty(tokenResponse.ErrCode)) { return BadRequest($"换取token失败: {tokenResponse?.ErrMsg}"); } var userInfoUrl = $"https://api.weixin.qq.com/sns/userinfo?access_token={tokenResponse.AccessToken}&openid={tokenResponse.OpenId}"; var userInfo = await client.GetFromJsonAsync<WechatUserInfo>(userInfoUrl); var user = await _userService.FindOrCreateUserByOpenId(userInfo.OpenId, userInfo); var jwt = GenerateJwt(user.Id); return Ok(new { token = jwt, user = user }); }

注意几个坑:GetFromJsonAsync需要配置JSON反序列化时忽略大小写;微信返回的错误结构里同时包含errcode和errmsg,而成功结构里是access_token、expires_in、openid,两个模型最好都处理。另外,code参数在回调URL里可能是code=xxx,有些场景code会变成oauth_code,尽量兼容解析。

5.4 第三步:小程序jscode2session和获取手机号

小程序端调用wx.login拿到code后传给后端,后端代码和网页登录换token类似,只是接口地址换成了jscode2session:

public async Task<IActionResult> MiniProgramLogin(string code) { var client = _httpClientFactory.CreateClient(); var url = $"https://api.weixin.qq.com/sns/jscode2session?appid={_wechatConfig.AppId}&secret={_wechatConfig.AppSecret}&js_code={code}&grant_type=authorization_code"; var session = await client.GetFromJsonAsync<JsCode2SessionResult>(url); if (session == null || session.OpenId == null) { return BadRequest("jscode2session失败"); } var user = await _userService.FindOrCreateUserByOpenId(session.OpenId, null); return Ok(new { token = GenerateJwt(user.Id) }); }

这里得到的session_key不要丢,如果需要用老方案解密手机号,它才是核心密钥。如果采用新方案获取手机号,需要先获取接口调用凭据access_token,再调wxa/business/getuserphonenumber。access_token是用AppSecret去换的全局票据,有缓存机制,通常用https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET,有效时间约7200秒。项目中我会把它缓存在内存里,带一个提前5分钟的过期预留,避免每个手机号请求都重新去换token。

public async Task<PhoneNumberResult> GetPhoneNumber(string phoneCode) { var accessToken = await GetAccessTokenAsync(); var client = _httpClientFactory.CreateClient(); var response = await client.PostAsJsonAsync( $"https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={accessToken}", new { code = phoneCode }); var result = await response.Content.ReadFromJsonAsync<PhoneNumberResult>(); return result; }

这个接口返回的手机号数据是加密的还是明文?实际返回的是JSON里嵌套的phone_info,里面直接就是purePhoneNumber和countryCode,前端用户授权后你就能拿到明文手机号。拿到后务必脱敏存储,至少把中间四位打码,完整号码要加密存储或放到专门的敏感信息表里。

5.5 老方案解密手机号的参考实现

如果因为兼容旧版本,必须自己解密,AES解密的核心代码可以这样写:

public string DecryptPhoneData(string encryptedData, string sessionKey, string iv) { using var aes = Aes.Create(); aes.KeySize = 128; aes.BlockSize = 128; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; aes.Key = Convert.FromBase64String(sessionKey).Take(16).ToArray(); aes.IV = Convert.FromBase64String(iv); ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); byte[] encryptedBytes = Convert.FromBase64String(encryptedData); byte[] plainBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length); return Encoding.UTF8.GetString(plainBytes); }

解密后得到的JSON通常长这样:

{ "phoneNumber": "13800138000", "purePhoneNumber": "13800138000", "countryCode": "86", "watermark": { "timestamp": 1700000000, "appid": "wx1234567890abcdef" } }

这里重点说一下网上那些互相矛盾的实现:有的说key取sessionKey前16字节,有的说直接用Base64解码全部字节,还有的说IV是sessionKey的前16字节。老实讲,这些版本在不同时期、不同场景下都出现过能跑通的情况,根源是微信文档更新过、SDK版本不一致、以及很多人复制粘贴时改了一半。我的建议是:优先用官方最新的getuserphonenumber接口,不用碰解密;真要用老接口,就以你当前挂载的微信SDK版本对应的官方文档为准,并在代码里写注释注明文档版本号,避免后人踩坑。

6. 常见问题与避坑实录

6.1 redirect_uri参数错误,反复出现怎么查

先别急着改代码,按顺序排查:第一,授权回调域是否和回调URL的域名完全一致,注意必须一模一样,包括https、端口、是否带www;第二,redirect_uri是否做了URL编码,如果直接用HttpUtility.UrlEncode编码,注意空格会变成+,微信要求%20,通常用Uri.EscapeDataString更稳;第三,回调地址是否可以被公网访问,微信服务器不像浏览器,它无法访问内网地址。我自己踩过一次特别隐蔽的坑:后台配置的域名是example.com,但前端生成链接时不小心带上了https://www.example.com,多了一个www,直接报错。

6.2 换token时提示code无效或已被使用

这个错误有两种常见场景。第一种是用户或测试脚本手动刷新了回调页面,同一个code被提交了两次,第一次成功后第二次必然报错,需要在前端或者后端做幂等处理,比如在state里记录一个"已消费"标记。第二种是code确实过期了,授权码有效期很短,如果你在用户授权之后设置了一个很慢的中间跳转流程,很可能走到后端时已经超时。处理方式是一律重新发起授权,不要尝试去"救"这个code。

6.3 明明扫码授权了,却拿不到nickname和头像

微信网页登录默认的scope=snsapi_login在低版本或部分场景下只能拿到openid和头像,要拿到昵称、性别、地区,需要确保授权链接里的scope包含snsapi_userinfo,并且回调换取access_token之后,再去调userinfo接口。如果用户曾拒绝过授权,微信会在授权页让用户重新确认,此时如果用户在微信设置里关闭了"允许第三方应用获取信息",即使在授权页点了同意,userinfo接口也可能返回空数据。这种问题大多发生在老微信版本上,处理办法是:拉取失败时降级显示为空,引导用户手动补填。

6.4 微信返回的access_token过期了,用户这边掉线吗

很多开发者容易把微信的access_token当成自己应用的登录态,直接存进Cookie或本地缓存,这是不对的。access_token的有效期通常是7200秒,两小时后过期,但用户不可能两小时就重新登录一次。正确做法是:用微信返回的openid先找到或创建自己的用户,再签发自己的登录态,比如JWT,有效期由你决定。微信的access_token只是你用来拉取用户信息的一次性凭证,业务会话不依赖它。数据库里如果需要持久化access_token,必须加密存储,并且设置过期时间字段,方便定期清理。

6.5 拿手机号之前先想想隐私合规

最后聊聊合规。手机号属于敏感个人信息,现在主流App在获取用户手机号前,都必须弹窗告知使用目的并取得用户明示同意。小程序里的getPhoneNumber组件本身就是一个授权动作,但你在后端存储时仍然要遵循"最小必要"原则:能不存就不存,必须存就脱敏、加密、设权限。

微信登录也是一样,你拿到的昵称、头像、地区虽然属于公开信息,但不能拿来随意做用户画像分析或在第三方之间共享。授权页面已经向用户展示了你要获取什么,如果后端实际拉取的范围超出了展示范围,一旦被用户投诉或应用市场抽查到,轻则下架整改,重则关闭开放平台权限。接入任何第三方登录,安全都只是一部分,合规意识才是决定这一个功能能不能长期存活的关键。

接入微信登录这几年,我最大的感受是:OAuth2.0本身并不复杂,难的是那些藏在细节里的安全校验和边界情况。一个state没校验,可能被人绑号;一个code打到日志,可能泄露身份;一个session_key随手传给前端,加密保护就形同虚设。设计第三方登录方案时,不妨多问自己几个问题:如果这个code被截获会怎样,如果这个token泄露会怎样,如果这条用户数据被恶意读取会怎样。把这些问题在纸上过一遍,再对照官方文档看代码,你会发现很多坑其实都写在文档里,只是刚动手时没耐心看而已。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询