Java实战:50行代码实现QQ登录和微博登录

个人网站最近添加了评论功能。为了方便用户在不注册的情况下发表评论,它将两个常用软件——QQ和微博——通过一键登录连接起来。总的来说,这很简单。可能有一个小坑,但不太多。它被完全记录下来,方便以后的人快速连接。

2。后台设计

在实际开始对接之前,让我们先谈谈后台设计由于是第三方登录,如何保存用户信息是不可避免的首先,需要明确的是,在用户成功登录到第三方后,我们只能得到一个代表用户唯一身份的标识(微博是真实的uid,QQ是加密的openId)和一个用于识别用户的访问令牌。当然,昵称、头像、性别等信息也很有限。第三方登录的关键是如何确保用户合法登录。如果确定登录和上次登录是同一个人并且不是假的

事实上,我们不必担心这个。以微博登录为例。登录成功后,用户会给我们回拨一个代码,然后我们会将代码交换到微博上获取访问令牌。如果代码是由用户随机填写的,这个级别肯定不会通过。因此,先前的担心有点多余。

的另一个问题是如何进入现有的用户系统。一些网站要求用户在成功登录后输入手机号码和验证码,或者要求用户重新注册账号和密码以绑定到第三方账户。我觉得这种用户体验的实现很差。当我遇到这样的网站时,我通常会直接关闭它们。我已经登录并让用户注册。搞什么鬼。因为我所做的是一个注释函数,我不希望注释用户通过现有的用户表,所以没有这样的事情。如果我想通过,我认为这只不过是在成功登录后默认将数据插入旧的用户表,然后将其与OpenUser表相关联,并判断用户在登录时是否添加了OpenUser身份验证。

本文的背景以Java为例

2.1。数据库设计

再谈数据库设计,为了扩展系统,我有一个专门的OpenUser表来存储第三方登录用户,主要字段如下:

qq行

< p >

使设计理论上可以无限扩展

2.2。认证过程

这里我只谈一下我的计划。将访问令牌写入cookie绝对不安全,因为访问令牌相当于第三方网站的临时密码,如果被他人窃取,可以随意用于做坏事。用户成功登录后,我们可以自己生成令牌。即使这样的令牌被泄露,它也只会被随意评论,几乎没有损失。然而,例如,如果访问令牌被泄露,人们可以使用该访问令牌发送微博、删除微博、给予更多关注等。随意,这是非常危险的。当然,如果你不希望令牌泄漏,你也可以通过绑定IP来限制它。

认证是首先判断cookie中是否有我们自己的令牌,然后判断它是否合法,然后判断第三方授权是否过期等。

QQ登录

3.1。实名认证

QQ登录我们连接到QQ互联网,地址:https://connect.qq.com,首先,我们需要注册一个开发商和实名认证,我们需要持有身份证照片,所以我们不会谈论细节。

3.2。创建应用程序

进入应用程序管理页面(https://connect.qq.com/manage.html#/)创建应用程序,根据实际需要创建网站应用程序还是移动应用程序。我是来申请网站的:

qq行

< p >

第一步:

qq行

< p >

第二步:

qq行

< p >

将在提交后自动提交审核,主要检查您的数据是否与存档的数据一致。所有材料必须与存档的材料相同,否则审核将无法通过:

qq行

< p >

。当然,这些材料可以在以后进行修改。成功应用后,您将获得appId和appKey。

3.3。引导用户登录

您可以在这里下载一些可视资料,在页面的适当位置放置一个QQ登录按钮,点击后,引导用户进入授权页面:

qq行

< p >

代码:

功能打开窗口(网址,宽度,高度){ width = width | | 600高度=高度| | 400;var left =(windows . screen . width-width)/2;var top =(窗口.屏幕.高度-高度)/2;window.open(url," _blank "," toolbar=yes,location=yes,directories = no,status=no,menubar=yes,scrollbars = yes,resizable = no,copyhistory=yes,left=" left ",top=" top ",width=" width ",height = " height ";}功能QqLogon(){ var QqAppId = ' 424323422 ';//appid var QQ authpath = ' http://www.test.com/auth'从上述应用程序中获得;//以前设置的回调地址var状态= ' fjdslfjsdlkfd//必须传输防止CSRF攻击的随机参数,并在成功登录后传输回来。最好由后台生成并验证合法性打开窗口。response _ type = token & client _ id = $ { QqAppId } & redirect _ uri = $ { encodueRiComponent(QqAuthPath)} & state = $ { state } `);}

将打开一个授权页面,每个人都应该熟悉该页面:

qq行

< p >

。当我到达这里时,我遇到了一个问题。官方文件(https://wiki.connect.qq.com)称,成功登录后,将首先返回一个代码。然后我用代码接口换了访问令牌,然后我试了很多次,换了两个账户。我发现我每次都直接返回访问令牌,这为我节省了一步。我不知道是什么情况,情绪低落微信搜索网上项目聚集地获取更多实用课程

3.4。获取访问令牌

现在假设我们都直接获取访问令牌(因为我不明白为什么QQ会直接返回,这与文档中所说的不同),但是当授权回调时,访问令牌将被放在#之后,并且网址中的哈希值似乎不会被转移到后台(似乎就是这种情况)。如果您有任何不正确的意见,您只能编写一个临时页面,如

@ request mapping("/auth QQ ")public void auth QQ(http servlet request request)。Http servlet响应)抛出异常{//QQ登录有点特殊,参数放在#后,后台无法获取#后的参数,只有JS可以作为中间转换字符串html = "

" " " " " " " " " " " " " " " " " " " " ";response.getWriter()。打印(html);}

3.5 .获取openId

根据访问令牌接口获取用户的openId。请特别注意,此开放标识对于QQ号码appId是唯一的,换句话说,当同一个QQ号码登录到两个不同的AppId时获得的开放标识是不同的。顺便说一下,QQ登录相关的界面真的很“随意”,所有的都是最简单的获取请求,所以对接非常顺利微信搜索网上项目聚集地获取更多实用课程

直接查看代码:

//根据访问令牌//交换openId//错误示例:回调(““错误”:100016,“错误_描述”:“访问令牌检查失败”});//正确的示例:回调(“client _ id”:“10x xxxx 49”、“OpenID”:“cf2xxxxxx 9 f4c”});字符串结果= Httpsutil . get(" Https://graph . QQ . com/oaut h2.0/me?访问令牌= "访问令牌);映射resp = parseQQAuthResponse(结果);//此方法将结果传递给map integer error code =(integer)resp . get(“error”);字符串错误消息=(字符串)响应获取(“错误描述”);字符串openId =(字符串)分别获取(“OpenID”);if(错误代码!= null)返回新的错误结果(错误代码,“无法获取QQ用户openId:”错误消息);

3.6。获取信息,如用户的头像昵称

//获取信息,如用户的昵称,头像,{RET: 0,消息:'',昵称:'',...} RET不是0表示失败结果= HTTP sutil . get(“HTTP://graph . QQ . com/user/get _ user _ info?access _ token = " AccessToken " & oauth _ consumer _ key = " AppId " & openId = " OpenId);resp = JsonUtil.parseJsonToMap(结果);整数ret =(整数)resget(“ret”);字符串消息=(字符串)分别获取(“消息”);if(ret!= 0)返回新的错误结果(“无法获取用户QQ信息:”消息);//用户昵称可能有4字节的utf-8字符,默认情况下MySQL不支持,直接插入会报告错误,因此string inckname = string util . filter F8 mb4((字符串)resp.get(“昵称”)。trim();//此方法可由百度使用//图片URL _ QQ _ 2 = QQ的100*100头像,图片URL _ 2 = QQ的100&100空间头像,QQ头像可能不存在,且空间头像必须有StrAvatar =(字符串)RESP。获取(“图片URL _ QQ _ 2”);如果化身=(字符串)resp . get(“figure URL _ 2”);字符串性别=(字符串)对应(“性别”);

3.7。注意事项

当这一步主要涉及第三方时,就结束了,不是很简单吗?接下来就是如何插入数据库、如何保存令牌、写入会话等。

有几点需要注意:

需要注意数据库中是否有用户被更改、未添加或修改。不要重复添加它们;QQ昵称昵称有各种奇怪的字符,包括表情符号。默认情况下,MySQL不会打开utf8mb4,因此直接插入会报告错误,因此需要将其过滤掉。有必要兼容各种错误。该界面将同时返回QQ头像和空间头像。QQ头像可能不存在,但空间头像必须存在。回拨地址必须与应用的域名相同,否则将报告错误。QQ互联网有一个巨大的漏洞,有时它显示你已经登录,但点击授权管理不断报告错误。此时,您只需要注销并再次登录。授权后,用户可以在到期前提前取消授权;微信搜索网上项目聚集地获取更多实用课程

的相关文件已经在官方网站上写得很详细了,但是很混乱:http://wiki.connect.qq.com/

登录了

4.1到微博。关于实名认证

,我就不多说了。当登录到http://open.weibo.com/,并注册为开发者时,很容易找到相关条目。实名认证完全一样。

4.2。创建应用程序

单击链接http://open.weibo.com/apps/new?排序=网络创建网络应用程序:

qq行

< p >

创建结果后,改进相关信息,主要有以下几点:

qq行

< p >

我不会介绍它们全部,我能理解它们全部

微博登录不需要注册网站,但对网站本身有一定的要求,不能建立一个外壳网站供他人审查,这肯定会导致审查失败。

4.3。引导用户登录

微博可视材料(https://open.weibo.com/wiki/微博标识下载)下载到这里。在页面的适当位置放置一个登录按钮:

功能微博登录(){ letweibo appid = ' 432432让WeiBoAuthPath = ' http://www . test . com/auth Weibo ';open window(` https://API . Weibo . com/oaut H2/authorize?client _ id = $ { WeiboaPPid } & response _ type = code & redirect _ uri = $ { encodeURIComponent(WeiboauthPath)} `);}

微博登录有一个优势。第一次登录需要授权,第二次登录只会是一个flash,登录会自动成功。没有必要指出。用户体验非常好。

< p >

4.4。获得访问令牌

登录将返回一个代码。根据代码交换访问令牌:

string params = " client _ id = " appid " & client _ secret = " appsecret " & grant _ type = authority _ code " " & redirect _ uri = " urutil . encode(auth path)" & code = " code;accesstokenstring结果的交换代码= http sutil . post(" https://API . Weibo . com/oaut H2/access _ token ",参数);映射resp = JsonUtil.toObject(结果,新类型引用(){ });整数错误代码=(整数)分别获取(“错误代码”);字符串错误=(字符串)响应获取(“错误”);字符串错误消息=(字符串)响应获取(“错误描述”);if(错误代码!= null &错误代码!= 0)返回新的错误结果(错误代码,错误(错误消息==null?" ":ErrorMSG));字符串访问令牌=(字符串)响应获取(“访问令牌”);字符串uid =(字符串)分别获取(“uid”);//此uid是微博用户的唯一用户标识。您可以直接访问用户的微博主页INTEXPIRES = (INTEGER) RESP。获取(“过期”);//有效期,单位秒

大家都在看

相关专题