1
0
mirror of synced 2026-05-22 21:53:18 +00:00

Compare commits

..

46 Commits

Author SHA1 Message Date
yadong.zhang 65c60a61b3 🔖 发布1.14.0,解耦HTTP工具 2020-03-17 22:57:53 +08:00
yadong.zhang d5a8ffcab2 Merge pull request #61 from githubeacon/master
增加飞书授权登录
2020-01-26 21:08:43 +08:00
yadong.zhang c95c118f88 Merge pull request #65 from runningzyp/dev
更新文档
2020-01-26 21:07:13 +08:00
YunpengZhan fec9a3c214 更新文档 2020-01-19 18:05:03 +08:00
yadong.zhang 6439058bda 📝 更新文档 2020-01-07 20:43:44 +08:00
beacon a1d31018d3 增加飞书授权登录 2019-12-30 21:16:48 +08:00
yadong.zhang 2a9d8e81a1 Merge branch 'master' into dev
# Conflicts:
#	pom.xml
2019-12-26 12:36:52 +08:00
yadong.zhang dda873ca11 Merge pull request #59 from xkcoding/extract-http
♻️ 抽取 HTTP,具体实现交给使用者,解耦 hutool-http
2019-12-26 12:35:52 +08:00
Yangkai.Shen 8dc4b5d7d6 ♻️ 抽取 HTTP,具体实现交给使用者,解耦 hutool-http 2019-12-25 18:28:18 +08:00
yadong.zhang 2038f24b3b Merge branch 'dev' 2019-12-24 19:37:33 +08:00
yadong.zhang f8f13fdb10 Merge branch 'dev' of https://gitee.com/yadong.zhang/JustAuth into dev 2019-12-24 19:36:41 +08:00
yadong.zhang 697c07cccc 📝 更新文档,加入发版日期 2019-12-24 19:35:39 +08:00
yadong.zhang e868d43ca3 🥚 添加实用工具,方便每次发版批量更新依赖版本 2019-12-24 19:34:39 +08:00
yadong.zhang 0700d7ee25 🔖 更新版本 2019-12-24 19:33:17 +08:00
yadong.zhang 822b4806a1 🍻 调整微信平台获取用户性别的代码逻辑,单独适配微信平台 2019-12-24 19:22:38 +08:00
yadong.zhang ab8c24ee5c 🍻 调整过获取用户性别的逻辑 2019-12-24 18:47:57 +08:00
yadong.zhang cd24cbdd58 Merge pull request #57 from xkcoding/wechat-mp
 集成微信公众号登录,修改之前的微信登录为微信开放平台登录
2019-12-24 11:00:18 +08:00
Yangkai.Shen 4bc9c09610 📝 修改文档,区分公众平台和开放平台 2019-12-23 13:54:27 +08:00
Yangkai.Shen 4d2518e21a 集成微信公众号登录,修改之前的微信登录为微信开放平台登录 2019-12-23 13:47:40 +08:00
yadong.zhang f47dc074e7 update docs/index.html. 2019-12-23 09:54:52 +08:00
yadong.zhang b7f01549c1 update docs/index.html. 2019-12-23 09:49:15 +08:00
yadong.zhang 264294caee 📝 添加微博授权登录的帮助文档 2019-12-22 20:03:22 +08:00
yadong.zhang 19ec565004 🍻 增加微博授权登录的revoke方法,支持手动回收授权 2019-12-22 20:02:26 +08:00
yadong.zhang 028924ecbf 📝 完善文档 2019-12-22 16:58:34 +08:00
yadong.zhang d2d3232501 📝 完善文档 2019-12-22 16:52:32 +08:00
yadong.zhang 1206847576 📝 添加Gittalk 2019-12-22 16:34:42 +08:00
yadong.zhang 2490c0f1ff 📝 自定义404页面 2019-12-22 16:34:14 +08:00
yadong.zhang 2fd7255ad4 📝 支付宝登录文档的图片 2019-12-22 14:56:45 +08:00
yadong.zhang f7873d71b2 📝 完善文档 2019-12-12 15:05:26 +08:00
yadong.zhang 602b1eaf58 📝 添加支付宝授权登录的帮助文档 2019-12-12 15:03:39 +08:00
yadong.zhang 7c2bc82814 🎨 优化 2019-12-12 14:47:57 +08:00
yadong.zhang 28b764f0d2 📝 添加qq授权登录的帮助文档 2019-12-12 11:48:27 +08:00
yadong.zhang 2442661291 📝 添加qq授权登录的帮助文档 2019-12-12 11:48:07 +08:00
yadong.zhang abb121a57c 📝 添加qq授权登录的帮助文档 2019-12-12 11:47:54 +08:00
yadong.zhang 51603e18ad 📝 添加微信授权登录的帮助文档 2019-12-12 11:30:54 +08:00
yadong.zhang 77c9680333 📝 编写文档 2019-12-10 17:21:09 +08:00
yadong.zhang 525c406c92 🐛 修复抖音登录取值取错层级的问题(issue#I15SIG@Gitee) 2019-12-10 17:15:19 +08:00
yadong.zhang e65d87daa3 Merge branch 'dev' of https://gitee.com/yadong.zhang/JustAuth into dev 2019-12-05 17:39:48 +08:00
yadong.zhang 8639359f53 ⬆️ 依赖升级 2019-12-05 17:39:08 +08:00
yadong.zhang 9eda5aaf2b !11 注解更新、包版本升级
Merge pull request !11 from 燃點/master
2019-12-05 17:34:34 +08:00
yadong.zhang 9d6ceb3898 💩 2019-12-05 17:20:31 +08:00
yadong.zhang 7bb9864799 !12 注解更新、包版本升级
Merge pull request !12 from 燃點/master
2019-11-15 17:56:36 +08:00
刘勋 95e4db2315 alipay-sdk-version 升级 4.8.10.ALL 2019-11-12 18:17:10 +08:00
刘勋 fc4606dad3 fastjson 升级到 1.2.62 2019-11-12 18:15:21 +08:00
刘勋 31330a366d hutool-http 升级到5.0.5 2019-11-12 18:14:51 +08:00
刘勋 7364c203ab 增加无参构造 2019-11-12 18:10:26 +08:00
104 changed files with 2067 additions and 653 deletions
+7 -2
View File
@@ -25,6 +25,11 @@ hs_err_pid*
# exclude idea files
.idea
*.iml
*.sh
bin/codecov.sh
bin/deploy.sh
bin/docsify-cli.sh
bin/push.sh
bin/push-dev.sh
target
target
/pom.xml.versionsBackup
+7 -6
View File
@@ -6,7 +6,7 @@
</p>
<p align="center">
<a target="_blank" href="https://search.maven.org/search?q=JustAuth">
<img src="https://img.shields.io/badge/Maven Central-1.13.1-blue.svg" ></img>
<img src="https://img.shields.io/badge/Maven Central-1.14.0-blue.svg" ></img>
</a>
<a target="_blank" href="https://gitee.com/yadong.zhang/JustAuth/blob/master/LICENSE">
<img src="https://img.shields.io/apm/l/vim-mode.svg?color=yellow" ></img>
@@ -15,7 +15,7 @@
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" ></img>
</a>
<a target="_blank" href="https://apidoc.gitee.com/yadong.zhang/JustAuth/" title="API文档">
<img src="https://img.shields.io/badge/Api Docs-1.13.1-orange.svg" ></img>
<img src="https://img.shields.io/badge/Api Docs-1.14.0-orange.svg" ></img>
</a>
<a target="_blank" href="https://docs.justauth.whnb.wang" title="参考文档">
<img src="https://img.shields.io/badge/Docs-latest-blueviolet.svg" ></img>
@@ -44,7 +44,7 @@
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/oschina.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/alipay.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="微信开放平台"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/taobao.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/google.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/facebook.png" width="20"></td>
@@ -97,7 +97,7 @@ These artifacts are available from Maven Central:
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.13.1</version>
<version>1.14.0</version>
</dependency>
```
- Using JustAuth
@@ -140,7 +140,9 @@ authRequest.login(callback);
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/oschina.png" width="20"> | [AuthOschinaRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java) | <a href="https://www.oschina.net/openapi/docs/oauth2_authorize" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/alipay.png" width="20"> | [AuthAlipayRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java) | <a href="https://alipay.open.taobao.com/docs/doc.htm?spm=a219a.7629140.0.0.336d4b70GUKXOl&treeId=193&articleId=105809&docType=1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"> | [AuthQqRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java) | <a href="https://wiki.connect.qq.com/%E4%BD%BF%E7%94%A8authorization_code%E8%8E%B7%E5%8F%96access_token" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"> | [AuthWeChatRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java) | <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="微信开放平台"> | [AuthWeChatOpenRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatOpenRequest.java) | <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="微信公众平台"> | [AuthWeChatMpRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatMpRequest.java) | <a href="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="企业微信"> | [AuthWeChatEnterpriseRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseRequest.java) | <a href="https://open.work.weixin.qq.com/api/doc#90000/90135/90664" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/taobao.png" width="20"> | [AuthTaobaoRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java) | <a href="https://open.taobao.com/doc.htm?spm=a219a.7386797.0.0.4e00669acnkQy6&source=search&docId=105590&docType=1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/google.png" width="20"> | [AuthGoogleRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java) | <a href="https://developers.google.com/identity/protocols/OpenIDConnect" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/facebook.png" width="20"> | [AuthFacebookRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java) | <a href="https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow" target="_blank">参考文档</a> |
@@ -154,7 +156,6 @@ authRequest.login(callback);
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/pinterest.png" width="20"> | [AuthPinterestRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java) | <a href="https://developers.pinterest.com/docs/api/overview/?" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/stackoverflow.png" width="20"> | [AuthStackOverflowRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java) | <a href="https://api.stackexchange.com/docs/authentication" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/huawei.png" width="20"> | [AuthHuaweiRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java) | <a href="https://developer.huawei.com/consumer/cn/devservice/doc/30101" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"> | [AuthWeChatEnterpriseRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseRequest.java) | <a href="https://open.work.weixin.qq.com/api/doc#90000/90135/90664" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/kujiale.png" width="20"> | [AuthKujialeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java) | <a href="https://open.kujiale.com/open/apps/2/docs?doc_id=95" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitlab.png" width="20"> | [AuthGitlabRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGitlabRequest.java) | <a href="https://docs.gitlab.com/ee/api/oauth2.html" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/meituan.png" width="20"> | [AuthMeituanRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMeituanRequest.java) | <a href="http://open.waimai.meituan.com/openapi_docs/oauth/" target="_blank">参考文档</a> |
+7 -6
View File
@@ -6,7 +6,7 @@
</p>
<p align="center">
<a target="_blank" href="https://search.maven.org/search?q=JustAuth">
<img src="https://img.shields.io/badge/Maven Central-1.13.1-blue.svg" ></img>
<img src="https://img.shields.io/badge/Maven Central-1.14.0-blue.svg" ></img>
</a>
<a target="_blank" href="https://gitee.com/yadong.zhang/JustAuth/blob/master/LICENSE">
<img src="https://img.shields.io/apm/l/vim-mode.svg?color=yellow" ></img>
@@ -15,7 +15,7 @@
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" ></img>
</a>
<a target="_blank" href="https://apidoc.gitee.com/yadong.zhang/JustAuth/" title="API文档">
<img src="https://img.shields.io/badge/Api Docs-1.13.1-orange.svg" ></img>
<img src="https://img.shields.io/badge/Api Docs-1.14.0-orange.svg" ></img>
</a>
<a target="_blank" href="https://docs.justauth.whnb.wang" title="参考文档">
<img src="https://img.shields.io/badge/Docs-latest-blueviolet.svg" ></img>
@@ -44,7 +44,7 @@
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/oschina.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/alipay.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="微信开放平台"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/taobao.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/google.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/facebook.png" width="20"></td>
@@ -97,7 +97,7 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.13.1</version>
<version>1.14.0</version>
</dependency>
```
- 调用api
@@ -146,7 +146,9 @@ authRequest.login(callback);
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/oschina.png" width="20"> | [AuthOschinaRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java) | <a href="https://www.oschina.net/openapi/docs/oauth2_authorize" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/alipay.png" width="20"> | [AuthAlipayRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java) | <a href="https://alipay.open.taobao.com/docs/doc.htm?spm=a219a.7629140.0.0.336d4b70GUKXOl&treeId=193&articleId=105809&docType=1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"> | [AuthQqRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java) | <a href="https://wiki.connect.qq.com/%E4%BD%BF%E7%94%A8authorization_code%E8%8E%B7%E5%8F%96access_token" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"> | [AuthWeChatRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java) | <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="微信开放平台"> | [AuthWeChatOpenRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatOpenRequest.java) | <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="微信公众平台"> | [AuthWeChatMpRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatMpRequest.java) | <a href="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="企业微信"> | [AuthWeChatEnterpriseRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseRequest.java) | <a href="https://open.work.weixin.qq.com/api/doc#90000/90135/90664" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/taobao.png" width="20"> | [AuthTaobaoRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java) | <a href="https://open.taobao.com/doc.htm?spm=a219a.7386797.0.0.4e00669acnkQy6&source=search&docId=105590&docType=1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/google.png" width="20"> | [AuthGoogleRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java) | <a href="https://developers.google.com/identity/protocols/OpenIDConnect" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/facebook.png" width="20"> | [AuthFacebookRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java) | <a href="https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow" target="_blank">参考文档</a> |
@@ -160,7 +162,6 @@ authRequest.login(callback);
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/pinterest.png" width="20"> | [AuthPinterestRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java) | <a href="https://developers.pinterest.com/docs/api/overview/?" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/stackoverflow.png" width="20"> | [AuthStackOverflowRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java) | <a href="https://api.stackexchange.com/docs/authentication" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/huawei.png" width="20"> | [AuthHuaweiRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java) | <a href="https://developer.huawei.com/consumer/cn/devservice/doc/30101" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"> | [AuthWeChatEnterpriseRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseRequest.java) | <a href="https://open.work.weixin.qq.com/api/doc#90000/90135/90664" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/kujiale.png" width="20"> | [AuthKujialeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java) | <a href="https://open.kujiale.com/open/apps/2/docs?doc_id=95" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitlab.png" width="20"> | [AuthGitlabRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGitlabRequest.java) | <a href="https://docs.gitlab.com/ee/api/oauth2.html" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/meituan.png" width="20"> | [AuthMeituanRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMeituanRequest.java) | <a href="http://open.waimai.meituan.com/openapi_docs/oauth/" target="_blank">参考文档</a> |
+35
View File
@@ -0,0 +1,35 @@
#!/bin/bash
#-----------------------------------------------------------
# 参考自 hutool 工具
# 此脚本用于每次升级justauth时替换相应位置的版本号
#-----------------------------------------------------------
pwd=$(pwd)
echo "当前路径:$pwd"
if [ -n "$1" ];then
new_version="$1"
old_version=`cat $pwd/bin/version.txt`
echo "$old_version 替换为新版本 $new_version"
else
# 参数错误,退出
echo "ERROR: 请指定新版本!"
exit
fi
if [ ! -n "$old_version" ]; then
echo "ERROR: 旧版本不存在,请确认bin/version.txt中信息正确"
exit
fi
# 替换README.md等文件中的版本
sed -i "s/${old_version}/${new_version}/g" $pwd/README.md
sed -i "s/${old_version}/${new_version}/g" $pwd/README.en-US.md
sed -i "s/${old_version}/${new_version}/g" $pwd/docs/README.md
sed -i "s/${old_version}/${new_version}/g" $pwd/docs/_coverpage.md
# 替换pom.xml中的版本
sed -i "s/${old_version}/${new_version}/g" $pwd/pom.xml
# 保留新版本号
echo "$new_version" > $pwd/bin/version.txt
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
#------------------------------------------------
# 参考自 hutool 工具
# 升级justauth版本,包括:
# 1. 升级pom.xml中的版本号
# 2. 替换README.md中的版本号
#------------------------------------------------
if [ ! -n "$1" ]; then
echo "ERROR: 新版本不存在,请指定参数1"
exit
fi
# 替换所有模块pom.xml中的版本
mvn versions:set -DnewVersion=$1
# 替换其它地方的版本
source $(pwd)/bin/repVersion.sh "$1"
+1
View File
@@ -0,0 +1 @@
1.14.0
+7 -6
View File
@@ -9,7 +9,7 @@
</p>
<p align="center">
<a target="_blank" href="https://search.maven.org/search?q=JustAuth">
<img src="https://img.shields.io/badge/Maven Central-1.13.1-blue.svg" ></img>
<img src="https://img.shields.io/badge/Maven Central-1.14.0-blue.svg" ></img>
</a>
<a target="_blank" href="https://gitee.com/yadong.zhang/JustAuth/blob/master/LICENSE">
<img src="https://img.shields.io/apm/l/vim-mode.svg?color=yellow" ></img>
@@ -18,7 +18,7 @@
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" ></img>
</a>
<a target="_blank" href="https://apidoc.gitee.com/yadong.zhang/JustAuth/" title="API文档">
<img src="https://img.shields.io/badge/Api Docs-1.13.1-orange.svg" ></img>
<img src="https://img.shields.io/badge/Api Docs-1.14.0-orange.svg" ></img>
</a>
<a target="_blank" href="https://docs.justauth.whnb.wang" title="参考文档">
<img src="https://img.shields.io/badge/Docs-latest-blueviolet.svg" ></img>
@@ -63,8 +63,8 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具
| :computer: 平台 | :coffee: API类 | :page_facing_up: SDK |
|:------:|:-------:|:-------:|
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitee.png" width="20"> | [AuthGiteeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | <a href="https://gitee.com/api/v5/oauth_doc#list_1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/github.png" width="20"> | [AuthGithubRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | <a href="https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/weibo.png" width="20"> | [AuthWeiboRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | <a href="https://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/github.png" width="20"> | [AuthGithubRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java) | <a href="https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/weibo.png" width="20"> | [AuthWeiboRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeiboRequest.java) | <a href="https://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/dingtalk.png" width="20"> | [AuthDingTalkRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java) | <a href="https://open-doc.dingtalk.com/microapp/serverapi2/kymkv6" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/baidu.png" width="20"> | [AuthBaiduRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java) | <a href="http://developer.baidu.com/wiki/index.php?title=docs/oauth" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/coding.png" width="25"> | [AuthCodingRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java) | <a href="https://open.coding.net/references/oauth/" target="_blank">参考文档</a> |
@@ -72,7 +72,9 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/oschina.png" width="20"> | [AuthOschinaRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java) | <a href="https://www.oschina.net/openapi/docs/oauth2_authorize" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/alipay.png" width="20"> | [AuthAlipayRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java) | <a href="https://alipay.open.taobao.com/docs/doc.htm?spm=a219a.7629140.0.0.336d4b70GUKXOl&treeId=193&articleId=105809&docType=1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"> | [AuthQqRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java) | <a href="https://wiki.connect.qq.com/%E4%BD%BF%E7%94%A8authorization_code%E8%8E%B7%E5%8F%96access_token" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"> | [AuthWeChatRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java) | <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="微信开放平台"> | [AuthWeChatOpenRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatOpenRequest.java) | <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="微信公众平台"> | [AuthWeChatMpRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatMpRequest.java) | <a href="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="企业微信"> | [AuthWeChatEnterpriseRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseRequest.java) | <a href="https://open.work.weixin.qq.com/api/doc#90000/90135/90664" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/taobao.png" width="20"> | [AuthTaobaoRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java) | <a href="https://open.taobao.com/doc.htm?spm=a219a.7386797.0.0.4e00669acnkQy6&source=search&docId=105590&docType=1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/google.png" width="20"> | [AuthGoogleRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java) | <a href="https://developers.google.com/identity/protocols/OpenIDConnect" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/facebook.png" width="20"> | [AuthFacebookRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java) | <a href="https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow" target="_blank">参考文档</a> |
@@ -86,7 +88,6 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/pinterest.png" width="20"> | [AuthPinterestRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java) | <a href="https://developers.pinterest.com/docs/api/overview/?" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/stackoverflow.png" width="20"> | [AuthStackOverflowRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java) | <a href="https://api.stackexchange.com/docs/authentication" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/huawei.png" width="20"> | [AuthHuaweiRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java) | <a href="https://developer.huawei.com/consumer/cn/devservice/doc/30101" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"> | [AuthWeChatEnterpriseRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseRequest.java) | <a href="https://open.work.weixin.qq.com/api/doc#90000/90135/90664" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/kujiale.png" width="20"> | [AuthKujialeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java) | <a href="https://open.kujiale.com/open/apps/2/docs?doc_id=95" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitlab.png" width="20"> | [AuthGitlabRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGitlabRequest.java) | <a href="https://docs.gitlab.com/ee/api/oauth2.html" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/meituan.png" width="20"> | [AuthMeituanRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMeituanRequest.java) | <a href="http://open.waimai.meituan.com/openapi_docs/oauth/" target="_blank">参考文档</a> |
+27
View File
@@ -0,0 +1,27 @@
**非常感谢您对JustAuth的关注**,您现在查询的内容,资料库中暂时没有,我们后续会补充上。
您可能还会需要以下文档:
- [OAuth的授权流程是什么样的?](https://docs.justauth.whnb.wang/#/oauth)
- [如何使用JustAuth](https://docs.justauth.whnb.wang/#/how-to-use)
- [提问与回答?](https://docs.justauth.whnb.wang/#/Q&A)
- [如何集成Github](https://docs.justauth.whnb.wang/#/oauth/github)
- [如何集成Gitee](https://docs.justauth.whnb.wang/#/oauth/gitee)
- [如何集成支付宝?](https://docs.justauth.whnb.wang/#/oauth/alipay)
- [如何自定义state](https://docs.justauth.whnb.wang/#/customize-the-state-cache)
- [如何自定义接入自己搭建的oauth平台?](https://docs.justauth.whnb.wang/#/customize-the-oauth)
- [有哪些配套项目?](https://docs.justauth.whnb.wang/#/supporting)
### 如果还是没有您想要的内容,您可以:
1. (建议) 提Issue 【[github](https://github.com/justauth/JustAuth/issues)】 | 【[gitee](https://gitee.com/yadong.zhang/JustAuth/issues)】
2. 本页面底部直接留言
3. 关注公众号(公众号会不定期推送相关内容),扫下方二维码关注公众号:
<img src="https://gitee.com/yadong.zhang/static/raw/master/wx/wechat_account.jpg" width="200" />
4. 加微信群(群内有各个优秀开源项目的作者和技术大神),微信扫下方二维码后加我好友(**注:一定要备注JustAUth,无备注的一律不加**):
<img src="https://gitee.com/yadong.zhang/static/raw/master/wx/wx.png" width="170"/>
5. 加QQ群:QQ搜索`230017570`(该QQ群为JustAuth官方技术讨论群,禁止群内打广告!)
+1 -1
View File
@@ -1,6 +1,6 @@
![](_media/logo.png)
# JustAuth <small>1.13.1</small>
# JustAuth <small>1.14.0</small>
<strong>史上最全的整合第三方登录的开源库</strong>
Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

+9 -7
View File
@@ -7,17 +7,19 @@
- [Q&A](Q&A.md)
- 集成第三方
- [√ Gitee登录](oauth/gitee.md)
- [Github登录](oauth/github.md)
- [qq登录](oauth/qq.md)
- [微信登录](oauth/wechat.md)
- [登录](oauth/weibo.md)
- [支付宝登录](oauth/alipay.md)
- [Github登录](oauth/github.md)
- [qq登录](oauth/qq.md)
- [√ 微信开放平台登录](oauth/wechat_open.md)
- [信企业版登录](oauth/wechatEnterprise.md)
- [微信公众平台登录](oauth/wechat_mp.md)
- [√ 微博登录](oauth/weibo.md)
- [√ 支付宝登录](oauth/alipay.md)
- [百度登录](oauth/baidu.md)
- [Coding登录](oauth/coding.md)
- [钉钉登录](oauth/dingtalk.md)
- [开源中国登录](oauth/oschina.md)
- [淘宝登录](oauth/taobao.md)
- [腾讯云登录](oauth/tenchentCloud.md)
- [腾讯云登录](oauth/tencentCloud.md)
- [Google登录](oauth/google.md)
- [Facebook登录](oauth/facebook.md)
- [抖音登录](oauth/douyin.md)
@@ -30,12 +32,12 @@
- [Pinterest登录](oauth/pinterest.md)
- [Stackoverflow登录](oauth/stackoverflow.md)
- [华为登录](oauth/huawei.md)
- [微信企业版登录](oauth/wechatEnterprise.md)
- [√ 酷家乐登录](oauth/kujiale.md)
- [Gitlab登录](oauth/gitlab.md)
- [美团登录](oauth/meituan.md)
- [饿了么登录](oauth/eleme.md)
- [CSDN登录](oauth/csdn.md)
- [飞书登录](oauth/feishu.md)
- 高级特性
- [使用State](using-state.md)
- [自定义state缓存](customize-the-state-cache.md)
+4
View File
@@ -26,6 +26,10 @@
- 添加测试用例:UrlBuilder 、GlobalAuthUtil
- <img src="https://avatars0.githubusercontent.com/u/283483?s=180&v=4" width="20"> · Chris Smowton : <a href="https://github.com/smowton" target="_blank">[Github]</a>
- 添加测试用例:StringUtils
- <img src="https://avatars1.githubusercontent.com/u/31759178?s=88&v=4" width="20"> · githubeacon : <a href="https://github.com/githubeacon" target="_blank">[Github]</a>
- 增加飞书授权登录
- <img src="https://avatars3.githubusercontent.com/u/20242284?s=88&u=2aeb7576bd61392e9fd94227d2b3048a9aea6f73&v=4" width="20"> · runningzyp : <a href="https://github.com/runningzyp" target="_blank">[Github]</a>
- 修改文案错误
- 千年等一回,我只为等你...
ps: 如有遗漏,请告知
+2 -2
View File
@@ -163,6 +163,6 @@ public Object revokeAuth(@PathVariable("source") String source, @PathVariable("t
- [Nutzboot版](https://github.com/EggsBlue/nutzboot-justauth-demo): NutzBoot集成JustAuth的demo by [蛋蛋](https://github.com/EggsBlue)
- [Blade版](https://github.com/justauth/blade-justauth-demo): Blade集成JustAuth的demo
## springboot starter插件
## starter插件
- [justauth-spring-boot-starter](https://github.com/xkcoding/justauth-spring-boot-starter): Spring Boot 集成 JustAuth 的最佳实践 by [xkcoding](https://github.com/xkcoding)
- [justauth-spring-boot-starter-demo](https://github.com/justauth/justauth-spring-boot-starter-demo): Spring Boot 使用 justauth-spring-boot-starter 快速集成 JustAuth by [xkcoding](https://github.com/xkcoding)
- [justauth-spring-security-starter](https://github.com/justauth/justauth-spring-security-starter): JustAuth整合Spring security的 starter依赖 by [luoqiz](https://github.com/luoqiz)
+43 -6
View File
@@ -16,13 +16,18 @@
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
<link rel="stylesheet" href="//unpkg.com/gitalk/dist/gitalk.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.css">
</head>
<body>
<div id="app">Please wait...</div>
<div data-app id="app">Please wait...</div>
<script>
var num = 0;
window.$docsify = {
name: '<img src="./_media/cover.png" width="200"><br>Login, so easy',
el: '#app',
name: 'JustAuth',
logo: './_media/cover.png',
search: {
maxAge: 86400000,
noData: {
@@ -30,7 +35,7 @@
},
paths: 'auto',
placeholder: {
'/': '搜索'
'/': '输入您的关键词进行搜索'
}
},
repo: 'https://gitee.com/yadong.zhang/JustAuth',
@@ -39,7 +44,9 @@
subMaxLevel: 2,
auto2top: true,
coverpage: true,
autoHeader: true,
formatUpdated: '{YYYY}/{MM}/{DD} {HH}:{mm}:{ss}',
notFoundPage: '_404.md',
plugins: [
function (hook, vm) {
var footer = [
@@ -58,17 +65,47 @@
return html
+ '\n----\n'
+ 'Last modified {docsify-updated} '
+ '最后更新时间: {docsify-updated} '
+ editHtml
})
}
]
],
markdown: {
renderer: {
code: function(code, lang) {
if (lang === "mermaid") {
return (
'<div class="mermaid">' + mermaid.render('mermaid-svg-' + num++, code) + "</div>"
);
}
return this.origin.code.apply(this, arguments);
}
}
}
}
</script>
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mermaid@7.1.0/dist/mermaid.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
<script src="//unpkg.com/docsify-copy-code"></script>
<script src="//cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad:true});</script>
<script src="//unpkg.com/prismjs/components/prism-java.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/gitalk.min.js"></script>
<script src="//unpkg.com/gitalk/dist/gitalk.min.js"></script>
<script>
const gitalk = new Gitalk({
clientID: 'e58f172df200e88e266b',
clientSecret: 'ee22ce68934616f7de043a950cbdb7d613a03202',
repo: 'justauth-talk',
owner: 'zhangyd-c',
admin: ['zhangyd-c'],
id: location.hash,
// facebook-like distraction free mode
distractionFreeMode: false
})
</script>
<!-- 百度统计 -->
<script>
+1 -1
View File
@@ -67,7 +67,7 @@
- 网站B:可以理解成 Oschina
- 第三方C:可以理解成 Github
需求:你想通过Github第三方登录Oschina
需求:你想通过Github第三方登录Oschina。(_注:下面的内容为流程图,如果您在阅读的时候显示为纯文字,请刷新页面_)
<div class="mermaid">
sequenceDiagram
+211 -3
View File
@@ -1,7 +1,215 @@
(敬请期待...
## 1. 配置应用
## 1. 申请应用
### 1.1 创建应用
#### 1. 进入支付宝开放平台([open.alipay.com](https://open.alipay.com))并登录
#### 2. 点击“进入我的开放平台”
![](../_media/oauth/alipay_01.png)
#### 3. 通过 **开发者中心-网页&移动应用** 进入应用管理列表页
![](../_media/oauth/alipay_02.png)
![](../_media/oauth/alipay_03.png)
#### 4. 选择创建 **自定义接入** 应用
![](../_media/oauth/alipay_04.png)
#### 5. 填入相关信息确认创建
![](../_media/oauth/alipay_05.png)
#### 6. 进入应用详情后,点击【功能列表】中的【**+添加功能**】按钮,选择【获取会员信息】
![](../_media/oauth/alipay_06.png)
![](../_media/oauth/alipay_07.png)
### 1.2 配置密钥
开发者调用接口前需要先生成RSA密钥,RSA密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY)。生成密钥后在开放平台开发者中心进行密钥配置,配置完成后可以获取支付宝公钥(ALIPAY_PUBLIC_KEY)。
接下来我们要在【应用详情】最下面的【开发设置】中,配置密钥相关的内容
#### 1. 接口加签方式
此处生成密钥的详细说明可以参考:[生成 RSA 密钥 ](https://docs.open.alipay.com/291/105971/)
我们这儿简单介绍一种使用“公钥”加签的方式
a. 首先下载密钥生成工具:[Windows版](https://ideservice.alipay.com/ide/getPluginUrl.htm?clientType=assistant&platform=win&channelType=WEB)(请不要安装在含有空格的目录路径下) | [MAC_OS版](https://ideservice.alipay.com/ide/getPluginUrl.htm?clientType=assistant&platform=mac&channelType=WEB)
b. 点击 【生成密钥】 后,工具会自动生成商户应用公钥(public key)和应用私钥(private key),如下图所示:
![](../_media/oauth/alipay_08.png)
点击工具界面下方的 【打开文件位置】,即可找到生成的公私钥文件,这儿需要注意!
工具默认打开的是CSR目录,并不是我们生成的密钥的目录,如下图:
![](../_media/oauth/alipay_09.png)
我们只需要往前返回一级目录,就可看到 RSA密钥 文件夹,进入 RSA密钥 目录后就可看到我们刚刚生成的密钥文件,如下图所示:
![](../_media/oauth/alipay_10.png)
注意:应用私钥需要在JustAuth中配置。
c. 回到应用详情页面,点击【接口加签方式】后面的【设置】按钮,【加签模式】中选择【公钥】,然后在下方输入框中输入之前生成的【应用公钥2048.txt】文件内容
![](../_media/oauth/alipay_11.png)
保存设置后,将会生成一份【支付宝公钥】,注意:这个公钥会在OAuth中使用!
![](../_media/oauth/alipay_12.png)
**注意:**
生成的私钥需**妥善保管,避免遗失,不要泄露**。应用私钥需填写到代码中供签名时使用。应用公钥需提供给支付宝账号管理者上传到支付宝开放平台。
#### 2. 接口加签方式
关于IP白名单的配置方式,请参考:[开放平台 IP 白名单接入指南 ](https://docs.open.alipay.com/200/ipwhitelist)
#### 3. 支付宝网关
使用默认的即可:https://openapi.alipay.com/gateway.do
#### 4. 应用网关
这是选填字段,主要用来接收支付宝的异步通知。请开发者视个人情况选择使用
#### 5. 授权回调地址
这是关键内容,JustAuth中需要用到。比如本例配置的回调地址为:https://www.zhyd.me/oauth/callback/alipay
以上步骤比较繁杂,主要需要注意保存的信息为:
- 使用【支付宝开放平台开发助手】生成的【应用私钥】(应用私钥2048.txt)
- 配置【接口加签方式】时生成的【支付宝公钥】
- 授权回调地址
- APPID(应用详情左侧应用名称下方有标注)
### 1.3 应用提交审核
通过应用详情上方的【提交审核】按钮,将应用提交审核,大约需要1天左右。(ps:本例的应用,我从提交审核到审核完成,大约用了两个小时)
## 2. 集成JustAuth
## 3. 授权结果
### 2.1 引入依赖
```xml
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>${latest.version}</version>
</dependency>
```
`${latest.version}`表示当前最新的版本,可以在[这儿](https://github.com/justauth/JustAuth/releases)获取最新的版本信息。
### 2.2 创建Request
```java
AuthRequest authRequest = new AuthAlipayRequest(AuthConfig.builder()
.clientId("APPID")
.clientSecret("应用私钥")
.alipayPublicKey("支付宝公钥")
.redirectUri("https://www.zhyd.me/oauth/callback/alipay")
.build());
```
### 2.3 生成授权地址
我们可以直接使用以下方式生成第三方平台的授权链接:
```java
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
```
这个链接我们可以直接后台重定向跳转,也可以返回到前端后,前端控制跳转。前端控制的好处就是,可以将第三方的授权页嵌入到iframe中,适配网站设计。
### 2.4 以上完整代码如下
```java
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthAlipayRequest;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@RestController
@RequestMapping("/oauth")
public class RestAuthController {
@RequestMapping("/render")
public void renderAuth(HttpServletResponse response) throws IOException {
AuthRequest authRequest = getAuthRequest();
response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
}
@RequestMapping("/callback")
public Object login(AuthCallback callback) {
AuthRequest authRequest = getAuthRequest();
return authRequest.login(callback);
}
private AuthRequest getAuthRequest() {
return new AuthAlipayRequest(AuthConfig.builder()
.clientId("APPID")
.clientSecret("应用私钥")
.alipayPublicKey("支付宝公钥")
.redirectUri("https://www.zhyd.me/oauth/callback/alipay")
.build());
}
}
```
授权链接访问成功后会看到以下页面内容:
![](../_media/oauth/alipay_13.png)
手机扫码后会进去确认页面
![](../_media/oauth/alipay_14.png)
手机端点击确认后,web端将会跳转到授权认证页面
![](../_media/oauth/alipay_15.png)
点击同意授权即可完成支付宝的oauth登录。
## 3. 授权结果
```json
{
"code": 2000,
"msg": null,
"data": {
"uuid": "208xxxxx37",
"username": "张",
"nickname": "张",
"avatar": "https://tfs.alipayobjects.com/images/partner/T1vzlgXj8cXXXXXXXX",
"blog": null,
"company": null,
"location": "北京 北京市",
"email": null,
"remark": null,
"gender": "MALE",
"source": "ALIPAY",
"token": {
"accessToken": "authxxxx2d5b0a182A53",
"expireIn": 1296000,
"refreshToken": "authuxxxx4c1b0edb2X53",
"uid": "208xxxxx37",
"openId": null,
"accessCode": null,
"unionId": null,
"scope": null,
"tokenType": null,
"idToken": null,
"macAlgorithm": null,
"macKey": null,
"code": null,
"oauthToken": null,
"oauthTokenSecret": null,
"userId": null,
"screenName": null,
"oauthCallbackConfirmed": null
}
}
}
```
+8 -6
View File
@@ -55,7 +55,7 @@ AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder()
我们可以直接使用以下方式生成第三方平台的授权链接:
```java
String authorizeUrl = authRequest.authorize();
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
```
这个链接我们可以直接后台重定向跳转,也可以返回到前端后,前端控制跳转。前端控制的好处就是,可以将第三方的授权页嵌入到iframe中,适配网站设计。
@@ -65,7 +65,9 @@ String authorizeUrl = authRequest.authorize();
```java
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -81,13 +83,13 @@ public class RestAuthController {
@RequestMapping("/render")
public void renderAuth(HttpServletResponse response) throws IOException {
AuthRequest authRequest = getAuthRequest();
response.sendRedirect(authRequest.authorize());
response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
}
@RequestMapping("/callback")
public Object login(String code) {
public Object login(AuthCallback callback) {
AuthRequest authRequest = getAuthRequest();
return authRequest.login(code);
return authRequest.login(callback);
}
private AuthRequest getAuthRequest() {
@@ -106,7 +108,7 @@ public class RestAuthController {
## 3. 授权结果
注:数据脱敏
注:数据脱敏
```json
{
@@ -141,4 +143,4 @@ public class RestAuthController {
}
}
}
```
```
+7 -5
View File
@@ -52,7 +52,7 @@ AuthRequest authRequest = new AuthGithubRequest(AuthConfig.builder()
我们可以直接使用以下方式生成第三方平台的授权链接:
```java
String authorizeUrl = authRequest.authorize();
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
```
这个链接我们可以直接后台重定向跳转,也可以返回到前端后,前端控制跳转。前端控制的好处就是,可以将第三方的授权页嵌入到iframe中,适配网站设计。
@@ -61,8 +61,10 @@ String authorizeUrl = authRequest.authorize();
```java
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthGithubRequest;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -78,13 +80,13 @@ public class RestAuthController {
@RequestMapping("/render")
public void renderAuth(HttpServletResponse response) throws IOException {
AuthRequest authRequest = getAuthRequest();
response.sendRedirect(authRequest.authorize());
response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
}
@RequestMapping("/callback")
public Object login(String code) {
public Object login(AuthCallback callback) {
AuthRequest authRequest = getAuthRequest();
return authRequest.login(code);
return authRequest.login(callback);
}
private AuthRequest getAuthRequest() {
+3 -2
View File
@@ -81,6 +81,7 @@ String authorizeUrl = authRequest.authorize(String state, String scopeStr);
```java
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthKujialeRequest;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.request.AuthRequest;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -101,10 +102,10 @@ public class RestAuthController {
}
@RequestMapping("/callback")
public Object login(String code, String state) {
public Object login(AuthCallback callback) {
AuthRequest authRequest = getAuthRequest();
//此处如果对安全性有要求,请校验state参数
return authRequest.login(code);
return authRequest.login(callback);
}
private AuthRequest getAuthRequest() {
+93 -3
View File
@@ -1,7 +1,97 @@
(敬请期待...
## 1. 申请应用
### 1.登录QQ互联平台
https://connect.qq.com/
### 2.申请开发者
进入“应用管理”页面:[https://connect.qq.com/manage.html#/](https://connect.qq.com/manage.html#/)
如果是第一次使用,并且未进行过开发者认证,需要提交一下个人资料,待认证通过后方可创建应用。
### 3. 添加应用
依次点击:应用管理 -> 网站应用 -> 创建应用,应用信息提交后,等待审核通过即可
应用审核通过后如下:
![file](../_media/oauth/qq_01.png)
copy以下三个信息:`App ID``App Key``网站回调域`
## 2. 集成JustAuth
## 3. 授权结果
### 2.1 引入依赖
```xml
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>${latest.version}</version>
</dependency>
```
`${latest.version}`表示当前最新的版本,可以在[这儿](https://github.com/justauth/JustAuth/releases)获取最新的版本信息。
### 2.2 创建Request
```java
AuthRequest authRequest = new AuthQqRequest(AuthConfig.builder()
.clientId("App ID")
.clientSecret("App Key")
.redirectUri("网站回调域")
.build());
```
### 2.3 生成授权地址
我们可以直接使用以下方式生成第三方平台的授权链接:
```java
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
```
这个链接我们可以直接后台重定向跳转,也可以返回到前端后,前端控制跳转。前端控制的好处就是,可以将第三方的授权页嵌入到iframe中,适配网站设计。
### 2.4 以上完整代码如下
```java
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthQqRequest;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@RestController
@RequestMapping("/oauth")
public class RestAuthController {
@RequestMapping("/render")
public void renderAuth(HttpServletResponse response) throws IOException {
AuthRequest authRequest = getAuthRequest();
response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
}
@RequestMapping("/callback")
public Object login(AuthCallback callback) {
AuthRequest authRequest = getAuthRequest();
return authRequest.login(callback);
}
private AuthRequest getAuthRequest() {
return new AuthQqRequest(AuthConfig.builder()
.clientId("App ID")
.clientSecret("App Key")
.redirectUri("网站回调域")
.build());
}
}
```
## 3. 授权结果
暂无
-7
View File
@@ -1,7 +0,0 @@
(敬请期待...
## 1. 申请应用
## 2. 集成JustAuth
## 3. 授权结果
+10
View File
@@ -0,0 +1,10 @@
(敬请期待...
### 声明:
此文档适用于**微信公众平台**
## 1. 申请应用
## 2. 集成JustAuth
## 3. 授权结果
+168
View File
@@ -0,0 +1,168 @@
### 声明:
此文档适用于**微信开放平台**
## 1. 申请应用
### 1.注册微信开放平台账号
[https://open.weixin.qq.com/](https://open.weixin.qq.com/)。如果已有则忽略该步骤,直接进入第二步。
### 2. 申请开发者资质认证
这儿需要重点说明的是, 微信开放平台创建应用,需要申请**开发者资质认证**
![file](../_media/oauth/wechat_01.png)
如上图:账号中心->开发者资质认证
但是微信**不支持**个人开发者认证,必须要企业信息才能提交认证。
对于个人开发者来说,我们提供三种解决方案:
- 用自己公司的信息做认证(请确保合法合规)
- 找朋友帮忙认证
- 去TB或者其他平台花钱找人认证,这种方式一般支持:短期租、长期认证
### 3.创建第三方应用
认证通过后切换到“网站应用”标签页,点击“创建网站应用”按钮
![file](../_media/oauth/wechat_02.png)
![file](../_media/oauth/wechat_03.png)
创建完成后,就能在“网站应用”列表中看到相关信息
![file](../_media/oauth/wechat_04.png)
点击“查看”进入应用详情,可以看到 “OAuth三大件”:`Client ID``Client Secret``Callback URL`
![file](../_media/oauth/wechat_05.png)
**注意:**
- “授权回调域”填写对应域名即可。比如我想给我的博客 [https://www.zhyd.me](https://www.zhyd.me) 增加微信第三方登录,那么我在配回调地址时,就只需要填写 `www.zhyd.me`即可,实际我们自己开发程序时, 可以随便配置具体的回调地址,只要确保是在 `www.zhyd.me` 下的地址就行。本例中, 我在程序中配置的回调地址为:`https://www.zhyd.me/oauth/callback/wechat`
- 重要的事情说三遍:**一定要确保应用详情页的“接口信息”中的“微信登录”接口的状态为“已获得”!** **一定要确保应用详情页的“接口信息”中的“微信登录”接口的状态为“已获得”!** **一定要确保应用详情页的“接口信息”中的“微信登录”接口的状态为“已获得”!**否则一定会遇到这个问题:[“Scope参数错误或者Scope没有权限”是怎么回事?](../Q&A.md?id=_7scope参数错误或者scope没有权限是怎么回事?)
## 2. 集成JustAuth
### 2.1 引入依赖
```xml
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>${latest.version}</version>
</dependency>
```
`${latest.version}`表示当前最新的版本,可以在[这儿](https://github.com/justauth/JustAuth/releases)获取最新的版本信息。
### 2.2 创建Request
```java
AuthRequest authRequest = new AuthWeChatRequest(AuthConfig.builder()
.clientId("Client ID")
.clientSecret("Client Secret")
.redirectUri("https://www.zhyd.me/oauth/callback/wechat")
.build());
```
### 2.3 生成授权地址
我们可以直接使用以下方式生成第三方平台的授权链接:
```java
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
```
这个链接我们可以直接后台重定向跳转,也可以返回到前端后,前端控制跳转。前端控制的好处就是,可以将第三方的授权页嵌入到iframe中,适配网站设计。
### 2.4 以上完整代码如下
```java
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthWeChatOpenRequest;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@RestController
@RequestMapping("/oauth")
public class RestAuthController {
@RequestMapping("/render")
public void renderAuth(HttpServletResponse response) throws IOException {
AuthRequest authRequest = getAuthRequest();
response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
}
@RequestMapping("/callback")
public Object login(AuthCallback callback) {
AuthRequest authRequest = getAuthRequest();
return authRequest.login(callback);
}
private AuthRequest getAuthRequest() {
return new AuthWeChatOpenRequest(AuthConfig.builder()
.clientId("Client ID")
.clientSecret("Client Secret")
.redirectUri("https://www.zhyd.me/oauth/callback/wechat")
.build());
}
}
```
授权链接访问成功后会看到以下页面内容:
![file](../_media/oauth/wechat_06.png)
使用手机扫码后,将会进入确认授权页面
![file](../_media/oauth/wechat_07.png)
点击同意授权即可完成微信的oauth登录。
## 3. 授权结果
```json
{
"code": 2000,
"msg": null,
"data": {
"uuid": "xxxxxxx",
"username": "RD",
"nickname": "RD",
"avatar": "http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ereNicKErbtBVnraCnzjGia2ZWPSkI9Ok4ScrmkdiacgPN6D5qeYBf3iba2lXknE7YaMMHHRrMW6Op8eQ/132",
"blog": null,
"company": null,
"location": "中国-北京-",
"email": null,
"remark": null,
"gender": "MALE",
"source": "WECHAT_OPEN",
"token": {
"accessToken": "28_Bzvt4UxxxxFElOxxxxgTqIJmSE5LxB2Az7stFqYVnFoIhL7RbevA0Urc",
"expireIn": 7200,
"refreshToken": "28_vtarjUxxxxfKh0Axxxxe_vy7E62hAYkMJ5M_JT4gMXM7r1kT_SeKAQz8Ojow",
"uid": null,
"openId": "xxxxxxx",
"accessCode": null,
"unionId": "xxxxxxx",
"scope": null,
"tokenType": null,
"idToken": null,
"macAlgorithm": null,
"macKey": null,
"code": null,
"oauthToken": null,
"oauthTokenSecret": null,
"userId": null,
"screenName": null,
"oauthCallbackConfirmed": null
}
}
}
```
+151 -3
View File
@@ -1,7 +1,155 @@
(敬请期待...
## 1. 申请应用
### 1.注册微博开放平台账号
https://open.weibo.com/apps。如果已有则忽略该步骤,直接进入第二步。
### 2.创建应用
通过顶部菜单栏的【微连接-网站接入】或者直接点击【[网站接入](https://open.weibo.com/connect)】进入网站接入界面
![file](../_media/oauth/weibo_01.png)
点击【立即接入】按钮进入创建应用页面,填入**应用名称**,**应用分类**选择默认的“网页应用”即可
![file](../_media/oauth/weibo_02.png)
创建完成后会自动跳转到应用信息页面,如下图,根据提示完善应用即可
![file](../_media/oauth/weibo_03.png)
注:全部填写完成后,需要提交审核。
提交审核完成后,将Oauth需要用到的数据copy下来(下面截图取自我已经审核通过的应用):
![file](../_media/oauth/weibo_04.png)
![file](../_media/oauth/weibo_05.png)
微博平台的OAuth支持revoke操作,所以会有一个【取消授权回调页】配置。
## 2. 集成JustAuth
## 3. 授权结果
### 2.1 引入依赖
```xml
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>${latest.version}</version>
</dependency>
```
`${latest.version}`表示当前最新的版本,可以在[这儿](https://github.com/justauth/JustAuth/releases)获取最新的版本信息。
### 2.2 创建Request
```java
AuthRequest authRequest = new AuthWeiboRequest(AuthConfig.builder()
.clientId("App Key")
.clientSecret("App Secret")
.redirectUri("授权回调页")
.build());
```
### 2.3 生成授权地址
我们可以直接使用以下方式生成第三方平台的授权链接:
```java
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
```
这个链接我们可以直接后台重定向跳转,也可以返回到前端后,前端控制跳转。前端控制的好处就是,可以将第三方的授权页嵌入到iframe中,适配网站设计。
### 2.4 以上完整代码如下
```java
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthWeiboRequest;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@RestController
@RequestMapping("/oauth")
public class RestAuthController {
@RequestMapping("/render")
public void renderAuth(HttpServletResponse response) throws IOException {
AuthRequest authRequest = getAuthRequest();
response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
}
@RequestMapping("/callback")
public Object login(AuthCallback callback) {
AuthRequest authRequest = getAuthRequest();
return authRequest.login(callback);
}
@RequestMapping("/revoke/{token}")
public Object revokeAuth(@PathVariable("token") String token) throws IOException {
AuthRequest authRequest = getAuthRequest();
return authRequest.revoke(AuthToken.builder().accessToken(token).build());
}
private AuthRequest getAuthRequest() {
return new AuthWeiboRequest(AuthConfig.builder()
.clientId("App Key")
.clientSecret("App Secret")
.redirectUri("授权回调页")
.build());
}
}
```
授权链接访问成功后会看到以下页面内容:
![授权登录](../_media/oauth/weibo_06.png)
网页登录或者手机扫码登录并授权第三方应用的登录请求后,将会获取到用户的信息
## 3. 授权结果
```json
{
"code": 2000,
"msg": null,
"data": {
"uuid": "xxxxxxx",
"username": "七彩狼丿",
"nickname": "七彩狼丿",
"avatar": "https://tva3.sinaimg.cn/crop.0.0.1424.1424.50/649b9a6fjw8ezwz4inarqj213k13kwjh.jpg?KID=imgbed,tva&Expires=1577025808&ssig=Q7m4jDuwUt",
"blog": "https://www.zhyd.me",
"company": null,
"location": "北京 朝阳区",
"email": null,
"remark": "长大了,不得不接受一些事实",
"gender": "MALE",
"source": "WEIBO",
"token": {
"accessToken": "2.xxxxxCNUC",
"expireIn": 157679999,
"refreshToken": null,
"uid": "xxxxxxx",
"openId": "xxxxxxx",
"accessCode": null,
"unionId": null,
"scope": null,
"tokenType": null,
"idToken": null,
"macAlgorithm": null,
"macKey": null,
"code": null,
"oauthToken": null,
"oauthTokenSecret": null,
"userId": null,
"screenName": null,
"oauthCallbackConfirmed": null
}
}
}
```
+6 -3
View File
@@ -1,10 +1,13 @@
**配套Demo**
## 配套Demo
- [simple版](https://github.com/justauth/JustAuth-demo)
- [jFinal版](https://github.com/xkcoding/jfinal-justauth-demo): Jfinal集成JustAuth的demo by [xkcoding](https://github.com/xkcoding)
- [ActFramework版](https://github.com/xkcoding/act-justauth-demo): ActFramework 集成 JustAuth 的 demo by [xkcoding](https://github.com/xkcoding)
- [Nutzboot版](https://github.com/EggsBlue/nutzboot-justauth-demo): NutzBoot集成JustAuth的demo by [蛋蛋](https://github.com/EggsBlue)
- [Blade版](https://github.com/justauth/blade-justauth-demo): Blade集成JustAuth的demo
## 插件
## starter插件
- [justauth-spring-boot-starter](https://github.com/xkcoding/justauth-spring-boot-starter): Spring Boot 集成 JustAuth 的最佳实践 by [xkcoding](https://github.com/xkcoding)
- [justauth-spring-boot-starter-demo](https://github.com/justauth/justauth-spring-boot-starter-demo): Spring Boot 使用 justauth-spring-boot-starter 快速集成 JustAuth by [xkcoding](https://github.com/xkcoding)
- [justauth-spring-security-starter](https://github.com/justauth/justauth-spring-security-starter): JustAuth整合Spring security的 starter依赖 by [luoqiz](https://github.com/luoqiz)
### 更多项目请参考: https://github.com/justauth
+28
View File
@@ -1,3 +1,31 @@
## v1.14.0
### 2020/03/17
- 修改
- 合并[PR-59](https://github.com/justauth/JustAuth/pull/59),抽取HTTP,具体实现交给开发者,解耦 hutool-http,开发者可以视自己项目的依赖决定使用何种HTTP方式。详情请参考:https://github.com/xkcoding/simple-http
- 合并[PR-65](https://github.com/justauth/JustAuth/pull/65),修改错误文案
- 修复其他一些问题
## v1.13.2
### 2019/12/24
- 新增
- 增加微信、QQ、支付宝、微博授权登录的帮助文档
- 合并[PR#57](https://github.com/justauth/JustAuth/pull/57),增加微信公众号登录 by [@xkcoding](https://github.com/xkcoding)
- [帮助文档](https://docs.justauth.whnb.wang)中增加自定义的404页面
- [帮助文档](https://docs.justauth.whnb.wang)中增加Gittalk插件
- [帮助文档](https://docs.justauth.whnb.wang)中增加Java代码高亮的插件
- 增加`AuthUserGender#getWechatRealGender`方法,兼容获取微信平台的用户性别
- 修改
- 修复抖音登录取值取错层级的问题([issue#I15SIG@Gitee](https://gitee.com/yadong.zhang/JustAuth/issues/I15SIG)
- 完善异常提示的逻辑,支持传入Source(平台),发生异常时显示对应的source(平台)
- `checkState`方法从`AuthDefaultRequest`中提出到`AuthChecker`
- `AuthResponseStatus`枚举类中增加`ILLEGAL_STATUS``REQUIRED_REFRESH_TOKEN`两个枚举值
- `AuthSource`接口中增加`getName`方法,用来对外提供实际`source`的字符串值
- `AuthWeiboRequest`微博授权登录中实现`revoke`方法,支持手动回收授权
- [帮助文档](https://docs.justauth.whnb.wang)中修复[腾讯云登录]链接错误的问题
- 升级
- 升级相关依赖:lombok@v1.18.10hutool@5.0.5fastjson@1.2.62alipay@4.8.10.ALL[PR#11@Gitee](https://gitee.com/yadong.zhang/JustAuth/pulls/11)
## v1.13.1
### 2019/11/12
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
# 参考自 hutool 工具
help(){
echo "--------------------------------------------------------------------------"
echo ""
echo "usage: ./ja.sh [updv]"
echo ""
echo "-updv [version num] Update all justauth related versions."
echo ""
echo "--------------------------------------------------------------------------"
}
case "$1" in
'updv')
bin/updVersion.sh $2
;;
*)
help
esac
+9 -9
View File
@@ -6,13 +6,13 @@
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.13.1</version>
<version>1.14.0</version>
<name>JustAuth</name>
<url>https://gitee.com/yadong.zhang/JustAuth</url>
<description>
史上最全的整合第三方登录的开源库。目前已支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、
QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软、今日头条、Teambition、StackOverflow、Pinterest、人人、华为、
QQ、微信开放平台、微信公众平台、淘宝、Google、Facebook、抖音、领英、小米、微软、今日头条、Teambition、StackOverflow、Pinterest、人人、华为、
企业微信、酷家乐、Gitlab、美团、饿了么和推特等第三方平台的授权登录。
Login, so easy!
</description>
@@ -60,11 +60,11 @@
<maven-surefire-version>2.20</maven-surefire-version>
<maven-gpg-version>1.6</maven-gpg-version>
<maven.test.skip>false</maven.test.skip>
<hutool-version>4.6.1</hutool-version>
<lombok-version>1.18.4</lombok-version>
<simple-http.version>1.0</simple-http.version>
<lombok-version>1.18.10</lombok-version>
<junit-version>4.11</junit-version>
<fastjson-version>1.2.60</fastjson-version>
<alipay-sdk-version>3.7.4.ALL</alipay-sdk-version>
<fastjson-version>1.2.62</fastjson-version>
<alipay-sdk-version>4.8.10.ALL</alipay-sdk-version>
<jacoco-version>0.8.2</jacoco-version>
</properties>
@@ -76,9 +76,9 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>${hutool-version}</version>
<groupId>com.xkcoding.http</groupId>
<artifactId>simple-http</artifactId>
<version>${simple-http.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
@@ -47,6 +47,11 @@ public enum AuthDefaultSource implements AuthSource {
public String userInfo() {
return "https://api.weibo.com/2/users/show.json";
}
@Override
public String revoke() {
return "https://api.weibo.com/oauth2/revokeoauth2";
}
},
/**
* gitee
@@ -235,9 +240,9 @@ public enum AuthDefaultSource implements AuthSource {
}
},
/**
* 微信
* 微信开放平台
*/
WECHAT {
WECHAT_OPEN {
@Override
public String authorize() {
return "https://open.weixin.qq.com/connect/qrconnect";
@@ -258,6 +263,30 @@ public enum AuthDefaultSource implements AuthSource {
return "https://api.weixin.qq.com/sns/oauth2/refresh_token";
}
},
/**
* 微信公众平台
*/
WECHAT_MP {
@Override
public String authorize() {
return "https://open.weixin.qq.com/connect/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://api.weixin.qq.com/sns/oauth2/access_token";
}
@Override
public String userInfo() {
return "https://api.weixin.qq.com/sns/userinfo";
}
@Override
public String refresh() {
return "https://api.weixin.qq.com/sns/oauth2/refresh_token";
}
},
/**
* 淘宝
*/
@@ -694,6 +723,33 @@ public enum AuthDefaultSource implements AuthSource {
public String userInfo() {
return "https://api.twitter.com/1.1/users/show.json";
}
}
},
/**
* 飞书
* 注意:该平台暂时存在问题,请不要使用。待修复完成后会重新发版
*
* @since 1.14.0
*/
FEISHU{
@Override
public String authorize() {
return "https://open.feishu.cn/connect/qrconnect/page/sso/";
}
@Override
public String accessToken() {
return "https://open.feishu.cn/connect/qrconnect/oauth2/access_token/";
}
@Override
public String userInfo() {
return "https://open.feishu.cn/connect/qrconnect/oauth2/user_info/";
}
@Override
public String refresh() {
return "https://open.feishu.cn/connect/qrconnect/oauth2/access_token/";
}
}
}
@@ -61,4 +61,16 @@ public interface AuthSource {
default String refresh() {
throw new AuthException(AuthResponseStatus.UNSUPPORTED);
}
/**
* 获取Source的字符串名字
*
* @return name
*/
default String getName() {
if (this instanceof Enum) {
return String.valueOf(this);
}
return this.getClass().getSimpleName();
}
}
@@ -26,6 +26,8 @@ public enum AuthResponseStatus {
ILLEGAL_REDIRECT_URI(5006, "Illegal redirect uri"),
ILLEGAL_REQUEST(5007, "Illegal request"),
ILLEGAL_CODE(5008, "Illegal code"),
ILLEGAL_STATUS(5009, "Illegal state"),
REQUIRED_REFRESH_TOKEN(5010, "The refresh token is required; it must not be null"),
;
private int code;
@@ -2,6 +2,7 @@ package me.zhyd.oauth.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import me.zhyd.oauth.utils.StringUtils;
import java.util.Arrays;
@@ -18,25 +19,41 @@ public enum AuthUserGender {
* MALE/FAMALE为正常值,通过{@link AuthUserGender#getRealGender(String)}方法获取真实的性别
* UNKNOWN为容错值,部分平台不会返回用户性别,为了方便统一,使用UNKNOWN标记所有未知或不可测的用户性别信息
*/
MALE(1, ""),
FEMALE(0, ""),
UNKNOWN(-1, "未知");
MALE("1", ""),
FEMALE("0", ""),
UNKNOWN("-1", "未知");
private int code;
private String code;
private String desc;
public static AuthUserGender getRealGender(String code) {
if (code == null) {
/**
* 获取用户的实际性别,常规网站
*
* @param originalGender 用户第三方标注的原始性别
* @return 用户性别
*/
public static AuthUserGender getRealGender(String originalGender) {
if (null == originalGender || UNKNOWN.getCode().equals(originalGender)) {
return UNKNOWN;
}
String[] males = {"m", "", "1", "male"};
if (Arrays.asList(males).contains(code.toLowerCase())) {
if (Arrays.asList(males).contains(originalGender.toLowerCase())) {
return MALE;
}
String[] females = {"f", "", "0", "female"};
if (Arrays.asList(females).contains(code.toLowerCase())) {
return FEMALE;
return FEMALE;
}
/**
* 获取微信平台用户的实际性别,0表示未定义,1表示男性,2表示女性
*
* @param originalGender 用户第三方标注的原始性别
* @return 用户性别
* @since 1.13.2
*/
public static AuthUserGender getWechatRealGender(String originalGender) {
if (StringUtils.isEmpty(originalGender) || "0".equals(originalGender)) {
return AuthUserGender.UNKNOWN;
}
return UNKNOWN;
return getRealGender(originalGender);
}
}
@@ -1,5 +1,6 @@
package me.zhyd.oauth.exception;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
/**
@@ -17,6 +18,10 @@ public class AuthException extends RuntimeException {
this(AuthResponseStatus.FAILURE.getCode(), errorMsg);
}
public AuthException(String errorMsg, AuthSource source) {
this(AuthResponseStatus.FAILURE.getCode(), errorMsg, source);
}
public AuthException(int errorCode, String errorMsg) {
super(errorMsg);
this.errorCode = errorCode;
@@ -24,7 +29,15 @@ public class AuthException extends RuntimeException {
}
public AuthException(AuthResponseStatus status) {
super(status.getMsg());
this(status.getCode(), status.getMsg());
}
public AuthException(int errorCode, String errorMsg, AuthSource source) {
this(errorCode, String.format("%s [%s]", errorMsg, source.getName()));
}
public AuthException(AuthResponseStatus status, AuthSource source) {
this(status.getCode(), status.getMsg(), source);
}
public AuthException(String message, Throwable cause) {
@@ -1,8 +1,8 @@
package me.zhyd.oauth.model;
import lombok.Builder;
import lombok.Getter;
import lombok.*;
import me.zhyd.oauth.enums.AuthResponseStatus;
import java.io.Serializable;
/**
@@ -12,6 +12,7 @@ import java.io.Serializable;
* @since 1.8
*/
@Getter
@Setter
@Builder
public class AuthResponse<T> implements Serializable {
/**
@@ -3,6 +3,7 @@ package me.zhyd.oauth.model;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
@@ -1,8 +1,7 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -34,14 +33,13 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
String response = doPostAuthorizationCode(authCallback.getCode());
return getAuthToken(response);
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
String userInfo = response.body();
String userInfo = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(userInfo);
this.checkResponse(object);
return AuthUser.builder()
@@ -63,8 +61,8 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
@Override
public AuthResponse revoke(AuthToken authToken) {
HttpResponse response = doGetRevoke(authToken);
JSONObject object = JSONObject.parseObject(response.body());
String response = doGetRevoke(authToken);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
// 返回1表示取消授权成功,否则失败
AuthResponseStatus status = object.getIntValue("result") == 1 ? AuthResponseStatus.SUCCESS : AuthResponseStatus.FAILURE;
@@ -79,7 +77,7 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
.queryParam("client_id", this.config.getClientId())
.queryParam("client_secret", this.config.getClientSecret())
.build();
HttpResponse response = HttpRequest.get(refreshUrl).execute();
String response = HttpUtil.get(refreshUrl);
return AuthResponse.builder()
.code(AuthResponseStatus.SUCCESS.getCode())
.data(this.getAuthToken(response))
@@ -116,8 +114,8 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
}
}
private AuthToken getAuthToken(HttpResponse response) {
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
private AuthToken getAuthToken(String response) {
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
@@ -1,6 +1,5 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -30,8 +29,8 @@ public class AuthCodingRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doGetAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = doGetAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
@@ -42,8 +41,8 @@ public class AuthCodingRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
String response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
object = object.getJSONObject("data");
@@ -1,6 +1,5 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -30,16 +29,16 @@ public class AuthCsdnRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder().accessToken(accessTokenObject.getString("access_token")).build();
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
String response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
return AuthUser.builder()
.uuid(object.getString("username"))
@@ -1,7 +1,6 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthDefaultStateCache;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -39,7 +38,7 @@ public abstract class AuthDefaultRequest implements AuthRequest {
this.source = source;
this.authStateCache = authStateCache;
if (!AuthChecker.isSupportedAuth(config, source)) {
throw new AuthException(AuthResponseStatus.PARAMETER_INCOMPLETE);
throw new AuthException(AuthResponseStatus.PARAMETER_INCOMPLETE, source);
}
// 校验配置合法性
AuthChecker.checkConfig(config, source);
@@ -75,7 +74,7 @@ public abstract class AuthDefaultRequest implements AuthRequest {
public AuthResponse login(AuthCallback authCallback) {
try {
AuthChecker.checkCode(source, authCallback);
this.checkState(authCallback.getState());
AuthChecker.checkState(authCallback.getState(), source, authStateCache);
AuthToken authToken = this.getAccessToken(authCallback);
AuthUser user = this.getUserInfo(authToken);
@@ -94,10 +93,15 @@ public abstract class AuthDefaultRequest implements AuthRequest {
*/
private AuthResponse responseError(Exception e) {
int errorCode = AuthResponseStatus.FAILURE.getCode();
String errorMsg = e.getMessage();
if (e instanceof AuthException) {
errorCode = ((AuthException) e).getErrorCode();
AuthException authException = ((AuthException) e);
errorCode = authException.getErrorCode();
if (StringUtils.isNotEmpty(authException.getErrorMsg())) {
errorMsg = authException.getErrorMsg();
}
}
return AuthResponse.builder().code(errorCode).msg(e.getMessage()).build();
return AuthResponse.builder().code(errorCode).msg(errorMsg).build();
}
/**
@@ -203,73 +207,62 @@ public abstract class AuthDefaultRequest implements AuthRequest {
* 通用的 authorizationCode 协议
*
* @param code code码
* @return HttpResponse
* @return Response
*/
protected HttpResponse doPostAuthorizationCode(String code) {
return HttpRequest.post(accessTokenUrl(code)).execute();
protected String doPostAuthorizationCode(String code) {
return HttpUtil.post(accessTokenUrl(code));
}
/**
* 通用的 authorizationCode 协议
*
* @param code code码
* @return HttpResponse
* @return Response
*/
protected HttpResponse doGetAuthorizationCode(String code) {
return HttpRequest.get(accessTokenUrl(code)).execute();
protected String doGetAuthorizationCode(String code) {
return HttpUtil.get(accessTokenUrl(code));
}
/**
* 通用的 用户信息
*
* @param authToken token封装
* @return HttpResponse
* @return Response
*/
@Deprecated
protected HttpResponse doPostUserInfo(AuthToken authToken) {
return HttpRequest.post(userInfoUrl(authToken)).execute();
protected String doPostUserInfo(AuthToken authToken) {
return HttpUtil.post(userInfoUrl(authToken));
}
/**
* 通用的 用户信息
*
* @param authToken token封装
* @return HttpResponse
* @return Response
*/
protected HttpResponse doGetUserInfo(AuthToken authToken) {
return HttpRequest.get(userInfoUrl(authToken)).execute();
protected String doGetUserInfo(AuthToken authToken) {
return HttpUtil.get(userInfoUrl(authToken));
}
/**
* 通用的post形式的取消授权方法
*
* @param authToken token封装
* @return HttpResponse
* @return Response
*/
@Deprecated
protected HttpResponse doPostRevoke(AuthToken authToken) {
return HttpRequest.post(revokeUrl(authToken)).execute();
protected String doPostRevoke(AuthToken authToken) {
return HttpUtil.post(revokeUrl(authToken));
}
/**
* 通用的post形式的取消授权方法
*
* @param authToken token封装
* @return HttpResponse
* @return Response
*/
protected HttpResponse doGetRevoke(AuthToken authToken) {
return HttpRequest.get(revokeUrl(authToken)).execute();
protected String doGetRevoke(AuthToken authToken) {
return HttpUtil.get(revokeUrl(authToken));
}
/**
* 校验回调传回的state
*
* @param state {@code state}一定不为空
*/
protected void checkState(String state) {
if (StringUtils.isEmpty(state) || !authStateCache.containsKey(state)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_REQUEST);
}
}
}
@@ -1,9 +1,8 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -12,7 +11,7 @@ import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.GlobalAuthUtils;
import me.zhyd.oauth.utils.UrlBuilder;
/**
@@ -41,8 +40,8 @@ public class AuthDingTalkRequest extends AuthDefaultRequest {
String code = authToken.getAccessCode();
JSONObject param = new JSONObject();
param.put("tmp_auth_code", code);
HttpResponse response = HttpRequest.post(userInfoUrl(authToken)).body(param.toJSONString()).execute();
JSONObject object = JSON.parseObject(response.body());
String response = HttpUtil.post(userInfoUrl(authToken), param.toJSONString());
JSONObject object = JSON.parseObject(response);
if (object.getIntValue("errcode") != 0) {
throw new AuthException(object.getString("errmsg"));
}
@@ -89,7 +88,7 @@ public class AuthDingTalkRequest extends AuthDefaultRequest {
protected String userInfoUrl(AuthToken authToken) {
// 根据timestamp, appSecret计算签名值
String timestamp = System.currentTimeMillis() + "";
String urlEncodeSignature = GlobalAuthUtil.generateDingTalkSignature(config.getClientSecret(), timestamp);
String urlEncodeSignature = GlobalAuthUtils.generateDingTalkSignature(config.getClientSecret(), timestamp);
return UrlBuilder.fromBaseUrl(source.userInfo())
.queryParam("signature", urlEncodeSignature)
@@ -1,8 +1,7 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -39,16 +38,18 @@ public class AuthDouyinRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
JSONObject userInfoObject = JSONObject.parseObject(response.body());
String response = doGetUserInfo(authToken);
JSONObject userInfoObject = JSONObject.parseObject(response);
this.checkResponse(userInfoObject);
JSONObject dataObj = userInfoObject.getJSONObject("data");
return AuthUser.builder()
.uuid(userInfoObject.getString("union_id"))
.username(userInfoObject.getString("nickname"))
.nickname(userInfoObject.getString("nickname"))
.avatar(userInfoObject.getString("avatar"))
.remark(userInfoObject.getString("description"))
.gender(AuthUserGender.UNKNOWN)
.uuid(dataObj.getString("union_id"))
.username(dataObj.getString("nickname"))
.nickname(dataObj.getString("nickname"))
.avatar(dataObj.getString("avatar"))
.remark(dataObj.getString("description"))
.gender(AuthUserGender.getRealGender(dataObj.getString("gender")))
.location(String.format("%s %s %s", dataObj.getString("country"), dataObj.getString("province"), dataObj.getString("city")))
.token(authToken)
.source(source.toString())
.build();
@@ -83,16 +84,16 @@ public class AuthDouyinRequest extends AuthDefaultRequest {
* @return token对象
*/
private AuthToken getToken(String accessTokenUrl) {
HttpResponse response = HttpRequest.post(accessTokenUrl).execute();
String accessTokenStr = response.body();
JSONObject object = JSONObject.parseObject(accessTokenStr);
String response = HttpUtil.post(accessTokenUrl);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
JSONObject dataObj = object.getJSONObject("data");
return AuthToken.builder()
.accessToken(object.getString("access_token"))
.openId(object.getString("open_id"))
.expireIn(object.getIntValue("expires_in"))
.refreshToken(object.getString("refresh_token"))
.scope(object.getString("scope"))
.accessToken(dataObj.getString("access_token"))
.openId(dataObj.getString("open_id"))
.expireIn(dataObj.getIntValue("expires_in"))
.refreshToken(dataObj.getString("refresh_token"))
.scope(dataObj.getString("scope"))
.build();
}
@@ -1,9 +1,9 @@
package me.zhyd.oauth.request;
import cn.hutool.core.codec.Base64;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.constants.Constants;
import com.xkcoding.http.support.HttpHeader;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -14,7 +14,8 @@ import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.Base64Utils;
import me.zhyd.oauth.utils.GlobalAuthUtils;
import me.zhyd.oauth.utils.UrlBuilder;
import me.zhyd.oauth.utils.UuidUtils;
@@ -31,6 +32,9 @@ import java.util.Map;
*/
public class AuthElemeRequest extends AuthDefaultRequest {
private static final String CONTENT_TYPE_FORM = "application/x-www-form-urlencoded;charset=UTF-8";
private static final String CONTENT_TYPE_JSON = "application/json; charset=utf-8";
public AuthElemeRequest(AuthConfig config) {
super(config, AuthDefaultSource.ELEME);
}
@@ -41,18 +45,15 @@ public class AuthElemeRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
Map<String, String> form = new HashMap<>(4);
form.put("client_id", config.getClientId());
form.put("redirect_uri", config.getRedirectUri());
form.put("code", authCallback.getCode());
form.put("grant_type", "authorization_code");
HttpRequest request = HttpRequest.post(source.accessToken())
.form("client_id", config.getClientId())
.form("redirect_uri", config.getRedirectUri())
.form("code", authCallback.getCode())
.form("grant_type", "authorization_code");
// 设置header
this.setHeader(request);
HttpResponse response = request.execute();
JSONObject object = JSONObject.parseObject(response.body());
HttpHeader httpHeader = this.buildHeader(CONTENT_TYPE_FORM, this.getRequestId(), true);
String response = HttpUtil.post(source.accessToken(), form, httpHeader, false);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -75,11 +76,11 @@ public class AuthElemeRequest extends AuthDefaultRequest {
Map<String, Object> metasHashMap = new HashMap<>();
metasHashMap.put("app_key", config.getClientId());
metasHashMap.put("timestamp", timestamp);
String signature = GlobalAuthUtil.generateElemeSignature(config.getClientId(), config.getClientSecret(), timestamp, action, authToken.getAccessToken(), parameters);
String signature = GlobalAuthUtils.generateElemeSignature(config.getClientId(), config.getClientSecret(), timestamp, action, authToken
.getAccessToken(), parameters);
String requestId = this.getRequestId();
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("nop", "1.0.0");
paramsMap.put("id", requestId);
@@ -89,15 +90,10 @@ public class AuthElemeRequest extends AuthDefaultRequest {
paramsMap.put("params", parameters);
paramsMap.put("signature", signature);
HttpRequest request = HttpRequest.post(source.userInfo())
.body(JSONObject.toJSONBytes(paramsMap));
HttpHeader httpHeader = this.buildHeader(CONTENT_TYPE_JSON, requestId, false);
String response = HttpUtil.post(source.userInfo(), JSONObject.toJSONString(paramsMap), httpHeader);
// 设置header
this.setHeader(request, "application/json; charset=utf-8", requestId);
HttpResponse response = request.execute();
JSONObject object = JSONObject.parseObject(response.body());
JSONObject object = JSONObject.parseObject(response);
// 校验请求
if (object.containsKey("name")) {
@@ -121,15 +117,14 @@ public class AuthElemeRequest extends AuthDefaultRequest {
@Override
public AuthResponse refresh(AuthToken oldToken) {
HttpRequest request = HttpRequest.post(source.refresh())
.form("refresh_token", oldToken.getRefreshToken())
.form("grant_type", "refresh_token");
Map<String, String> form = new HashMap<>(2);
form.put("refresh_token", oldToken.getRefreshToken());
form.put("grant_type", "refresh_token");
// 设置header
this.setHeader(request);
HttpHeader httpHeader = this.buildHeader(CONTENT_TYPE_FORM, this.getRequestId(), true);
String response = HttpUtil.post(source.refresh(), form, httpHeader, false);
HttpResponse response = request.execute();
JSONObject object = JSONObject.parseObject(response.body());
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -146,29 +141,27 @@ public class AuthElemeRequest extends AuthDefaultRequest {
@Override
public String authorize(String state) {
return UrlBuilder.fromBaseUrl(super.authorize(state))
.queryParam("scope", "all")
.build();
return UrlBuilder.fromBaseUrl(super.authorize(state)).queryParam("scope", "all").build();
}
private String getBasic(String appKey, String appSecret) {
StringBuilder sb = new StringBuilder();
String encodeToString = Base64.encode((appKey + ":" + appSecret).getBytes());
String encodeToString = Base64Utils.encode((appKey + ":" + appSecret).getBytes());
sb.append("Basic").append(" ").append(encodeToString);
return sb.toString();
}
private void setHeader(HttpRequest request) {
setHeader(request, "application/x-www-form-urlencoded;charset=UTF-8", getRequestId());
request.header("Authorization", this.getBasic(config.getClientId(), config.getClientSecret()));
}
private void setHeader(HttpRequest request, String contentType, String requestId) {
request.header("Accept", "text/xml,text/javascript,text/html")
.header("Content-Type", contentType)
.header("Accept-Encoding", "gzip")
.header("User-Agent", "eleme-openapi-java-sdk")
.header("x-eleme-requestid", requestId);
private HttpHeader buildHeader(String contentType, String requestId, boolean auth) {
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Accept", "text/xml,text/javascript,text/html");
httpHeader.add(Constants.CONTENT_TYPE, contentType);
httpHeader.add("Accept-Encoding", "gzip");
httpHeader.add("User-Agent", "eleme-openapi-java-sdk");
httpHeader.add("x-eleme-requestid", requestId);
if (auth) {
httpHeader.add("Authorization", this.getBasic(config.getClientId(), config.getClientSecret()));
}
return httpHeader;
}
private String getRequestId() {
@@ -1,6 +1,5 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -30,8 +29,8 @@ public class AuthFacebookRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
@@ -42,8 +41,7 @@ public class AuthFacebookRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
String userInfo = response.body();
String userInfo = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(userInfo);
this.checkResponse(object);
return AuthUser.builder()
@@ -0,0 +1,113 @@
package me.zhyd.oauth.request;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.support.HttpHeader;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtils;
import me.zhyd.oauth.utils.UrlBuilder;
/**
* 注意:该平台暂时存在问题,请不要使用。待修复完成后会重新发版by yadong.zhang
*
* @author beacon
* @since 1.14.0
*/
@Deprecated
public class AuthFeishuRequest extends AuthDefaultRequest {
public AuthFeishuRequest(AuthConfig config) {
super(config, AuthDefaultSource.FEISHU);
throw new AuthException(AuthResponseStatus.FAILURE);
}
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
JSONObject requestObject = new JSONObject();
requestObject.put("app_id", config.getClientId());
requestObject.put("app_secret", config.getClientSecret());
requestObject.put("grant_type", "authorization_code");
requestObject.put("code", authCallback.getCode());
String response = HttpUtil.post(source.accessToken(), requestObject.toJSONString(), new HttpHeader()
.add("Content-Type", "application/json"));
JSONObject jsonObject = JSON.parseObject(response);
this.checkResponse(jsonObject);
return AuthToken.builder()
.accessToken(jsonObject.getString("access_token"))
.refreshToken(jsonObject.getString("refresh_token"))
.expireIn(jsonObject.getIntValue("expires_in"))
.tokenType(jsonObject.getString("token_type"))
.openId(jsonObject.getString("open_id"))
.build();
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
String accessToken = authToken.getAccessToken();
String response = HttpUtil.get(source.userInfo(), null, new HttpHeader()
.add("Content-Type", "application/json")
.add("Authorization", "Bearer " + accessToken), false);
JSONObject jsonObject = JSON.parseObject(response);
return AuthUser.builder()
.avatar(jsonObject.getString("AvatarUrl"))
.username(jsonObject.getString("Mobile"))
.email(jsonObject.getString("Email"))
.nickname("Name")
.build();
}
@Override
public AuthResponse refresh(AuthToken authToken) {
JSONObject requestObject = new JSONObject();
requestObject.put("app_id", config.getClientId());
requestObject.put("app_secret", config.getClientSecret());
requestObject.put("grant_type", "refresh_token");
requestObject.put("refresh_token", authToken.getRefreshToken());
String response = HttpUtil.post(source.refresh(), requestObject.toJSONString(), new HttpHeader()
.add("Content-Type", "application/json"));
JSONObject jsonObject = JSON.parseObject(response);
this.checkResponse(jsonObject);
return AuthResponse.builder()
.code(AuthResponseStatus.SUCCESS.getCode())
.data(AuthToken.builder()
.accessToken(jsonObject.getString("access_token"))
.refreshToken(jsonObject.getString("refresh_token"))
.expireIn(jsonObject.getIntValue("expires_in"))
.tokenType(jsonObject.getString("token_type"))
.openId(jsonObject.getString("open_id"))
.build())
.build();
}
@Override
public String authorize(String state) {
return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("app_id", config.getClientId())
.queryParam("redirect_uri", GlobalAuthUtils.urlEncode(config.getRedirectUri()))
.queryParam("state", getRealState(state))
.build();
}
/**
* 校验响应内容是否正确
*
* @param jsonObject 响应内容
*/
private void checkResponse(JSONObject jsonObject) {
if (jsonObject.getIntValue("code") != 0) {
throw new AuthException(jsonObject.getString("message"));
}
}
}
@@ -1,6 +1,5 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -29,8 +28,8 @@ public class AuthGiteeRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
@@ -43,8 +42,7 @@ public class AuthGiteeRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
String userInfo = response.body();
String userInfo = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(userInfo);
this.checkResponse(object);
return AuthUser.builder()
@@ -1,6 +1,5 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -10,7 +9,7 @@ import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.GlobalAuthUtils;
import java.util.Map;
@@ -32,8 +31,8 @@ public class AuthGithubRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
Map<String, String> res = GlobalAuthUtil.parseStringToMap(response.body());
String response = doPostAuthorizationCode(authCallback.getCode());
Map<String, String> res = GlobalAuthUtils.parseStringToMap(response);
this.checkResponse(res.containsKey("error"), res.get("error_description"));
@@ -46,8 +45,8 @@ public class AuthGithubRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
String response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object.containsKey("error"), object.getString("error_description"));
@@ -1,6 +1,5 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -30,8 +29,8 @@ public class AuthGitlabRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
JSONObject object = JSONObject.parseObject(response.body());
String response = doPostAuthorizationCode(authCallback.getCode());
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -46,8 +45,8 @@ public class AuthGitlabRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
String response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -1,8 +1,8 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.support.HttpHeader;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -31,8 +31,8 @@ public class AuthGoogleRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
@@ -45,10 +45,9 @@ public class AuthGoogleRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = HttpRequest.post(userInfoUrl(authToken))
.header("Authorization", "Bearer " + authToken.getAccessToken())
.execute();
String userInfo = response.body();
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Authorization", "Bearer " + authToken.getAccessToken());
String userInfo = HttpUtil.post(userInfoUrl(authToken), null, httpHeader);
JSONObject object = JSONObject.parseObject(userInfo);
this.checkResponse(object);
return AuthUser.builder()
@@ -1,8 +1,7 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -14,6 +13,9 @@ import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.UrlBuilder;
import java.util.HashMap;
import java.util.Map;
import static me.zhyd.oauth.enums.AuthResponseStatus.SUCCESS;
/**
@@ -43,13 +45,15 @@ public class AuthHuaweiRequest extends AuthDefaultRequest {
*/
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpRequest request = HttpRequest.post(source.accessToken())
.form("grant_type", "authorization_code")
.form("code", authCallback.getAuthorization_code())
.form("client_id", config.getClientId())
.form("client_secret", config.getClientSecret())
.form("redirect_uri", config.getRedirectUri());
return getAuthToken(request);
Map<String, String> form = new HashMap<>(5);
form.put("grant_type", "authorization_code");
form.put("code", authCallback.getAuthorization_code());
form.put("client_id", config.getClientId());
form.put("client_secret", config.getClientSecret());
form.put("redirect_uri", config.getRedirectUri());
String response = HttpUtil.post(source.accessToken(), form, false);
return getAuthToken(response);
}
/**
@@ -61,13 +65,14 @@ public class AuthHuaweiRequest extends AuthDefaultRequest {
*/
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = HttpRequest.post(source.userInfo())
.form("nsp_ts", System.currentTimeMillis())
.form("access_token", authToken.getAccessToken())
.form("nsp_fmt", "JS")
.form("nsp_svc", "OpenUP.User.getInfo")
.execute();
JSONObject object = JSONObject.parseObject(response.body());
Map<String, String> form = new HashMap<>(4);
form.put("nsp_ts", System.currentTimeMillis() + "");
form.put("access_token", authToken.getAccessToken());
form.put("nsp_fmt", "JS");
form.put("nsp_svc", "OpenUP.User.getInfo");
String response = HttpUtil.post(source.userInfo(), form, false);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -92,20 +97,18 @@ public class AuthHuaweiRequest extends AuthDefaultRequest {
*/
@Override
public AuthResponse refresh(AuthToken authToken) {
HttpRequest request = HttpRequest.post(source.refresh())
.form("client_id", config.getClientId())
.form("client_secret", config.getClientSecret())
.form("refresh_token", authToken.getRefreshToken())
.form("grant_type", "refresh_token");
return AuthResponse.builder()
.code(SUCCESS.getCode())
.data(getAuthToken(request))
.build();
Map<String, String> form = new HashMap<>(4);
form.put("client_id", config.getClientId());
form.put("client_secret", config.getClientSecret());
form.put("refresh_token", authToken.getRefreshToken());
form.put("grant_type", "refresh_token");
String response = HttpUtil.post(source.refresh(), form, false);
return AuthResponse.builder().code(SUCCESS.getCode()).data(getAuthToken(response)).build();
}
private AuthToken getAuthToken(HttpRequest request) {
HttpResponse response = request.execute();
JSONObject object = JSONObject.parseObject(response.body());
private AuthToken getAuthToken(String response) {
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -1,8 +1,7 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -66,11 +65,11 @@ public class AuthKujialeRequest extends AuthDefaultRequest {
@Override
public AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
String response = doPostAuthorizationCode(authCallback.getCode());
return getAuthToken(response);
}
private AuthToken getAuthToken(HttpResponse response) {
private AuthToken getAuthToken(String response) {
JSONObject accessTokenObject = checkResponse(response);
JSONObject resultObject = accessTokenObject.getJSONObject("d");
return AuthToken.builder()
@@ -80,9 +79,8 @@ public class AuthKujialeRequest extends AuthDefaultRequest {
.build();
}
private JSONObject checkResponse(HttpResponse response) {
String accessTokenStr = response.body();
JSONObject accessTokenObject = JSONObject.parseObject(accessTokenStr);
private JSONObject checkResponse(String response) {
JSONObject accessTokenObject = JSONObject.parseObject(response);
if (!"0".equals(accessTokenObject.getString("c"))) {
throw new AuthException(accessTokenObject.getString("m"));
}
@@ -92,11 +90,11 @@ public class AuthKujialeRequest extends AuthDefaultRequest {
@Override
public AuthUser getUserInfo(AuthToken authToken) {
String openId = this.getOpenId(authToken);
HttpResponse response = HttpRequest.get(UrlBuilder.fromBaseUrl(source.userInfo())
String response = HttpUtil.get(UrlBuilder.fromBaseUrl(source.userInfo())
.queryParam("access_token", authToken.getAccessToken())
.queryParam("open_id", openId)
.build()).execute();
JSONObject object = JSONObject.parseObject(response.body());
.build());
JSONObject object = JSONObject.parseObject(response);
if (!"0".equals(object.getString("c"))) {
throw new AuthException(object.getString("m"));
}
@@ -119,16 +117,16 @@ public class AuthKujialeRequest extends AuthDefaultRequest {
* @return openId
*/
private String getOpenId(AuthToken authToken) {
HttpResponse response = HttpRequest.get(UrlBuilder.fromBaseUrl("https://oauth.kujiale.com/oauth2/auth/user")
String response = HttpUtil.get(UrlBuilder.fromBaseUrl("https://oauth.kujiale.com/oauth2/auth/user")
.queryParam("access_token", authToken.getAccessToken())
.build()).execute();
.build());
JSONObject accessTokenObject = checkResponse(response);
return accessTokenObject.getString("d");
}
@Override
public AuthResponse refresh(AuthToken authToken) {
HttpResponse response = HttpRequest.post(refreshTokenUrl(authToken.getRefreshToken())).execute();
String response = HttpUtil.post(refreshTokenUrl(authToken.getRefreshToken()));
return AuthResponse.builder().code(AuthResponseStatus.SUCCESS.getCode()).data(getAuthToken(response)).build();
}
}
@@ -1,10 +1,11 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.constants.Constants;
import com.xkcoding.http.support.HttpHeader;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -43,12 +44,13 @@ public class AuthLinkedinRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
String accessToken = authToken.getAccessToken();
HttpResponse response = HttpRequest.get(userInfoUrl(authToken))
.header("Host", "api.linkedin.com")
.header("Connection", "Keep-Alive")
.header("Authorization", "Bearer " + accessToken)
.execute();
JSONObject userInfoObject = JSONObject.parseObject(response.body());
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Host", "api.linkedin.com");
httpHeader.add("Connection", "Keep-Alive");
httpHeader.add("Authorization", "Bearer " + accessToken);
String response = HttpUtil.get(userInfoUrl(authToken), null, httpHeader, false);
JSONObject userInfoObject = JSONObject.parseObject(response);
this.checkResponse(userInfoObject);
@@ -121,13 +123,16 @@ public class AuthLinkedinRequest extends AuthDefaultRequest {
* @return 用户的邮箱地址
*/
private String getUserEmail(String accessToken) {
HttpResponse emailResponse = HttpRequest.get("https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))")
.header("Host", "api.linkedin.com")
.header("Connection", "Keep-Alive")
.header("Authorization", "Bearer " + accessToken)
.execute();
JSONObject emailObj = JSONObject.parseObject(emailResponse.body());
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Host", "api.linkedin.com");
httpHeader.add("Connection", "Keep-Alive");
httpHeader.add("Authorization", "Bearer " + accessToken);
String emailResponse = HttpUtil.get("https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))");
JSONObject emailObj = JSONObject.parseObject(emailResponse);
this.checkResponse(emailObj);
Object obj = JSONPath.eval(emailObj, "$['elements'][0]['handle~']['emailAddress']");
return null == obj ? null : (String) obj;
}
@@ -145,7 +150,7 @@ public class AuthLinkedinRequest extends AuthDefaultRequest {
public AuthResponse refresh(AuthToken oldToken) {
String refreshToken = oldToken.getRefreshToken();
if (StringUtils.isEmpty(refreshToken)) {
throw new AuthException(AuthResponseStatus.UNSUPPORTED);
throw new AuthException(AuthResponseStatus.REQUIRED_REFRESH_TOKEN, source);
}
String refreshTokenUrl = refreshTokenUrl(refreshToken);
return AuthResponse.builder()
@@ -161,7 +166,7 @@ public class AuthLinkedinRequest extends AuthDefaultRequest {
*/
private void checkResponse(JSONObject object) {
if (object.containsKey("error")) {
throw new AuthException(object.getString("error_description"));
throw new AuthException(object.getString("error_description"), source);
}
}
@@ -172,12 +177,12 @@ public class AuthLinkedinRequest extends AuthDefaultRequest {
* @return token对象
*/
private AuthToken getToken(String accessTokenUrl) {
HttpResponse response = HttpRequest.post(accessTokenUrl)
.header("Host", "www.linkedin.com")
.contentType("application/x-www-form-urlencoded")
.execute();
String accessTokenStr = response.body();
JSONObject accessTokenObject = JSONObject.parseObject(accessTokenStr);
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Host", "www.linkedin.com");
httpHeader.add(Constants.CONTENT_TYPE, "application/x-www-form-urlencoded");
String response = HttpUtil.post(accessTokenUrl, null, httpHeader);
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
@@ -1,8 +1,7 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -15,6 +14,9 @@ import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.UrlBuilder;
import java.util.HashMap;
import java.util.Map;
/**
* 美团登录
*
@@ -33,13 +35,14 @@ public class AuthMeituanRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = HttpRequest.post(source.accessToken())
.form("app_id", config.getClientId())
.form("secret", config.getClientSecret())
.form("code", authCallback.getCode())
.form("grant_type", "authorization_code")
.execute();
JSONObject object = JSONObject.parseObject(response.body());
Map<String, String> form = new HashMap<>(4);
form.put("app_id", config.getClientId());
form.put("secret", config.getClientSecret());
form.put("code", authCallback.getCode());
form.put("grant_type", "authorization_code");
String response = HttpUtil.post(source.accessToken(), form, false);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -52,12 +55,13 @@ public class AuthMeituanRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = HttpRequest.post(source.userInfo())
.form("app_id", config.getClientId())
.form("secret", config.getClientSecret())
.form("access_token", authToken.getAccessToken())
.execute();
JSONObject object = JSONObject.parseObject(response.body());
Map<String, String> form = new HashMap<>(3);
form.put("app_id", config.getClientId());
form.put("secret", config.getClientSecret());
form.put("access_token", authToken.getAccessToken());
String response = HttpUtil.post(source.userInfo(), form, false);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -74,13 +78,14 @@ public class AuthMeituanRequest extends AuthDefaultRequest {
@Override
public AuthResponse refresh(AuthToken oldToken) {
HttpResponse response = HttpRequest.post(source.refresh())
.form("app_id", config.getClientId())
.form("secret", config.getClientSecret())
.form("refresh_token", oldToken.getRefreshToken())
.form("grant_type", "refresh_token")
.execute();
JSONObject object = JSONObject.parseObject(response.body());
Map<String, String> form = new HashMap<>(4);
form.put("app_id", config.getClientId());
form.put("secret", config.getClientSecret());
form.put("refresh_token", oldToken.getRefreshToken());
form.put("grant_type", "refresh_token");
String response = HttpUtil.post(source.refresh(), form, false);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -1,9 +1,8 @@
package me.zhyd.oauth.request;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.constants.Constants;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -42,8 +41,8 @@ public class AuthMiRequest extends AuthDefaultRequest {
}
private AuthToken getToken(String accessTokenUrl) {
HttpResponse response = HttpRequest.get(accessTokenUrl).execute();
String jsonStr = StrUtil.replace(response.body(), PREFIX, StrUtil.EMPTY);
String response = HttpUtil.get(accessTokenUrl);
String jsonStr = response.replace(PREFIX, Constants.EMPTY);
JSONObject accessTokenObject = JSONObject.parseObject(jsonStr);
if (accessTokenObject.containsKey("error")) {
@@ -65,9 +64,9 @@ public class AuthMiRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
// 获取用户信息
HttpResponse userResponse = doGetUserInfo(authToken);
String userResponse = doGetUserInfo(authToken);
JSONObject userProfile = JSONObject.parseObject(userResponse.body());
JSONObject userProfile = JSONObject.parseObject(userResponse);
if ("error".equalsIgnoreCase(userProfile.getString("result"))) {
throw new AuthException(userProfile.getString("description"));
}
@@ -89,8 +88,8 @@ public class AuthMiRequest extends AuthDefaultRequest {
String emailPhoneUrl = MessageFormat.format("{0}?clientId={1}&token={2}", "https://open.account.xiaomi.com/user/phoneAndEmail", config
.getClientId(), authToken.getAccessToken());
HttpResponse emailResponse = HttpRequest.get(emailPhoneUrl).execute();
JSONObject userEmailPhone = JSONObject.parseObject(emailResponse.body());
String emailResponse = HttpUtil.get(emailPhoneUrl);
JSONObject userEmailPhone = JSONObject.parseObject(emailResponse);
if (!"error".equalsIgnoreCase(userEmailPhone.getString("result"))) {
JSONObject emailPhone = userEmailPhone.getJSONObject("data");
authUser.setEmail(emailPhone.getString("email"));
@@ -1,8 +1,10 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.constants.Constants;
import com.xkcoding.http.support.HttpHeader;
import com.xkcoding.http.util.MapUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -15,7 +17,7 @@ import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.UrlBuilder;
import static me.zhyd.oauth.utils.GlobalAuthUtil.parseQueryToMap;
import java.util.Map;
/**
* 微软登录
@@ -44,13 +46,14 @@ public class AuthMicrosoftRequest extends AuthDefaultRequest {
* @return token对象
*/
private AuthToken getToken(String accessTokenUrl) {
HttpResponse response = HttpRequest.post(accessTokenUrl)
.header("Host", "https://login.microsoftonline.com")
.contentType("application/x-www-form-urlencoded")
.form(parseQueryToMap(accessTokenUrl))
.execute();
String accessTokenStr = response.body();
JSONObject accessTokenObject = JSONObject.parseObject(accessTokenStr);
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Host", "https://login.microsoftonline.com");
httpHeader.add(Constants.CONTENT_TYPE, "application/x-www-form-urlencoded");
Map<String, String> form = MapUtil.parseStringToMap(accessTokenUrl, false);
String response = HttpUtil.post(accessTokenUrl, form, httpHeader, false);
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
@@ -79,8 +82,11 @@ public class AuthMicrosoftRequest extends AuthDefaultRequest {
String token = authToken.getAccessToken();
String tokenType = authToken.getTokenType();
String jwt = tokenType + " " + token;
HttpResponse response = HttpRequest.get(userInfoUrl(authToken)).header("Authorization", jwt).execute();
String userInfo = response.body();
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Authorization", jwt);
String userInfo = HttpUtil.get(userInfoUrl(authToken), null, httpHeader, false);
JSONObject object = JSONObject.parseObject(userInfo);
this.checkResponse(object);
return AuthUser.builder()
@@ -1,6 +1,5 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -30,8 +29,8 @@ public class AuthOschinaRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
@@ -43,8 +42,8 @@ public class AuthOschinaRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
String response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
return AuthUser.builder()
.uuid(object.getString("id"))
@@ -1,8 +1,7 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.enums.AuthUserGender;
@@ -36,8 +35,8 @@ public class AuthPinterestRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
@@ -48,8 +47,9 @@ public class AuthPinterestRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
String userinfoUrl = userInfoUrl(authToken);
HttpResponse response = HttpRequest.get(userinfoUrl).setFollowRedirects(true).execute();
JSONObject object = JSONObject.parseObject(response.body());
// TODO: 是否需要 .setFollowRedirects(true)
String response = HttpUtil.get(userinfoUrl);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
JSONObject userObj = object.getJSONObject("data");
return AuthUser.builder()
@@ -1,9 +1,7 @@
package me.zhyd.oauth.request;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -14,7 +12,7 @@ import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.GlobalAuthUtils;
import me.zhyd.oauth.utils.StringUtils;
import me.zhyd.oauth.utils.UrlBuilder;
@@ -38,21 +36,21 @@ public class AuthQqRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doGetAuthorizationCode(authCallback.getCode());
String response = doGetAuthorizationCode(authCallback.getCode());
return getAuthToken(response);
}
@Override
public AuthResponse refresh(AuthToken authToken) {
HttpResponse response = HttpRequest.get(refreshTokenUrl(authToken.getRefreshToken())).execute();
String response = HttpUtil.get(refreshTokenUrl(authToken.getRefreshToken()));
return AuthResponse.builder().code(AuthResponseStatus.SUCCESS.getCode()).data(getAuthToken(response)).build();
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
String openId = this.getOpenId(authToken);
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
String response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response);
if (object.getIntValue("ret") != 0) {
throw new AuthException(object.getString("msg"));
}
@@ -82,27 +80,22 @@ public class AuthQqRequest extends AuthDefaultRequest {
* @return openId
*/
private String getOpenId(AuthToken authToken) {
HttpResponse response = HttpRequest.get(UrlBuilder.fromBaseUrl("https://graph.qq.com/oauth2.0/me")
String response = HttpUtil.get(UrlBuilder.fromBaseUrl("https://graph.qq.com/oauth2.0/me")
.queryParam("access_token", authToken.getAccessToken())
.queryParam("unionid", config.isUnionId() ? 1 : 0)
.build()).execute();
if (response.isOk()) {
String body = response.body();
String removePrefix = StrUtil.replace(body, "callback(", "");
String removeSuffix = StrUtil.replace(removePrefix, ");", "");
String openId = StrUtil.trim(removeSuffix);
JSONObject object = JSONObject.parseObject(openId);
if (object.containsKey("error")) {
throw new AuthException(object.get("error") + ":" + object.get("error_description"));
}
authToken.setOpenId(object.getString("openid"));
if (object.containsKey("unionid")) {
authToken.setUnionId(object.getString("unionid"));
}
return StringUtils.isEmpty(authToken.getUnionId()) ? authToken.getOpenId() : authToken.getUnionId();
.build());
String removePrefix = response.replace("callback(", "");
String removeSuffix = removePrefix.replace(");", "");
String openId = removeSuffix.trim();
JSONObject object = JSONObject.parseObject(openId);
if (object.containsKey("error")) {
throw new AuthException(object.get("error") + ":" + object.get("error_description"));
}
throw new AuthException("request error");
authToken.setOpenId(object.getString("openid"));
if (object.containsKey("unionid")) {
authToken.setUnionId(object.getString("unionid"));
}
return StringUtils.isEmpty(authToken.getUnionId()) ? authToken.getOpenId() : authToken.getUnionId();
}
/**
@@ -120,8 +113,8 @@ public class AuthQqRequest extends AuthDefaultRequest {
.build();
}
private AuthToken getAuthToken(HttpResponse response) {
Map<String, String> accessTokenObject = GlobalAuthUtil.parseStringToMap(response.body());
private AuthToken getAuthToken(String response) {
Map<String, String> accessTokenObject = GlobalAuthUtils.parseStringToMap(response);
if (!accessTokenObject.containsKey("access_token") || accessTokenObject.containsKey("code")) {
throw new AuthException(accessTokenObject.get("msg"));
}
@@ -1,9 +1,8 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.enums.AuthUserGender;
@@ -42,8 +41,8 @@ public class AuthRenrenRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
JSONObject userObj = JSONObject.parseObject(response.body()).getJSONObject("response");
String response = doGetUserInfo(authToken);
JSONObject userObj = JSONObject.parseObject(response).getJSONObject("response");
return AuthUser.builder()
.uuid(userObj.getString("id"))
@@ -65,8 +64,8 @@ public class AuthRenrenRequest extends AuthDefaultRequest {
}
private AuthToken getToken(String url) {
HttpResponse response = HttpRequest.post(url).execute();
JSONObject jsonObject = JSONObject.parseObject(response.body());
String response = HttpUtil.post(url);
JSONObject jsonObject = JSONObject.parseObject(response);
if (jsonObject.containsKey("error")) {
throw new AuthException("Failed to get token from Renren: " + jsonObject);
}
@@ -1,8 +1,10 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.constants.Constants;
import com.xkcoding.http.support.HttpHeader;
import com.xkcoding.http.util.MapUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.enums.AuthUserGender;
@@ -12,8 +14,9 @@ import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.UrlBuilder;
import java.util.Map;
import static me.zhyd.oauth.config.AuthDefaultSource.STACK_OVERFLOW;
import static me.zhyd.oauth.utils.GlobalAuthUtil.parseQueryToMap;
/**
* Stack Overflow登录
@@ -34,11 +37,12 @@ public class AuthStackOverflowRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
String accessTokenUrl = accessTokenUrl(authCallback.getCode());
HttpResponse response = HttpRequest.post(accessTokenUrl)
.contentType("application/x-www-form-urlencoded")
.form(parseQueryToMap(accessTokenUrl))
.execute();
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
Map<String, String> form = MapUtil.parseStringToMap(accessTokenUrl, false);
HttpHeader httpHeader = new HttpHeader();
httpHeader.add(Constants.CONTENT_TYPE, "application/x-www-form-urlencoded");
String response = HttpUtil.post(accessTokenUrl, form, httpHeader, false);
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
@@ -54,8 +58,8 @@ public class AuthStackOverflowRequest extends AuthDefaultRequest {
.queryParam("site", "stackoverflow")
.queryParam("key", this.config.getStackOverflowKey())
.build();
HttpResponse response = HttpRequest.get(userInfoUrl).execute();
JSONObject object = JSONObject.parseObject(response.body());
String response = HttpUtil.get(userInfoUrl);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
JSONObject userObj = object.getJSONArray("items").getJSONObject(0);
@@ -1,6 +1,5 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -10,7 +9,7 @@ import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.GlobalAuthUtils;
import me.zhyd.oauth.utils.UrlBuilder;
/**
@@ -36,8 +35,8 @@ public class AuthTaobaoRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doPostAuthorizationCode(authToken.getAccessCode());
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = doPostAuthorizationCode(authToken.getAccessCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
if (accessTokenObject.containsKey("error")) {
throw new AuthException(accessTokenObject.getString("error_description"));
}
@@ -47,7 +46,7 @@ public class AuthTaobaoRequest extends AuthDefaultRequest {
authToken.setUid(accessTokenObject.getString("taobao_user_id"));
authToken.setOpenId(accessTokenObject.getString("taobao_open_uid"));
String nick = GlobalAuthUtil.urlDecode(accessTokenObject.getString("taobao_user_nick"));
String nick = GlobalAuthUtils.urlDecode(accessTokenObject.getString("taobao_user_nick"));
return AuthUser.builder()
.uuid(accessTokenObject.getString("taobao_user_id"))
.username(nick)
@@ -1,8 +1,8 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.support.HttpHeader;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -14,6 +14,9 @@ import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import java.util.HashMap;
import java.util.Map;
/**
* Teambition授权登录
*
@@ -36,13 +39,14 @@ public class AuthTeambitionRequest extends AuthDefaultRequest {
*/
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = HttpRequest.post(source.accessToken())
.form("client_id", config.getClientId())
.form("client_secret", config.getClientSecret())
.form("code", authCallback.getCode())
.form("grant_type", "code")
.execute();
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
Map<String, String> form = new HashMap<>(4);
form.put("client_id", config.getClientId());
form.put("client_secret", config.getClientSecret());
form.put("code", authCallback.getCode());
form.put("grant_type", "code");
String response = HttpUtil.post(source.accessToken(), form, false);
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
@@ -56,10 +60,11 @@ public class AuthTeambitionRequest extends AuthDefaultRequest {
protected AuthUser getUserInfo(AuthToken authToken) {
String accessToken = authToken.getAccessToken();
HttpResponse response = HttpRequest.get(source.userInfo())
.header("Authorization", "OAuth2 " + accessToken)
.execute();
JSONObject object = JSONObject.parseObject(response.body());
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Authorization", "OAuth2 " + accessToken);
String response = HttpUtil.get(source.userInfo(), null, httpHeader, false);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -83,11 +88,12 @@ public class AuthTeambitionRequest extends AuthDefaultRequest {
public AuthResponse refresh(AuthToken oldToken) {
String uid = oldToken.getUid();
String refreshToken = oldToken.getRefreshToken();
HttpResponse response = HttpRequest.post(source.refresh())
.form("_userId", uid)
.form("refresh_token", refreshToken)
.execute();
JSONObject refreshTokenObject = JSONObject.parseObject(response.body());
Map<String, String> form = new HashMap<>(2);
form.put("_userId", uid);
form.put("refresh_token", refreshToken);
String response = HttpUtil.post(source.refresh(), form, false);
JSONObject refreshTokenObject = JSONObject.parseObject(response);
this.checkResponse(refreshTokenObject);
@@ -1,6 +1,5 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -30,8 +29,8 @@ public class AuthTencentCloudRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doGetAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = doGetAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
@@ -42,8 +41,8 @@ public class AuthTencentCloudRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
String response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
object = object.getJSONObject("data");
@@ -1,6 +1,5 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
@@ -31,8 +30,8 @@ public class AuthToutiaoRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doGetAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = doGetAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
@@ -45,9 +44,9 @@ public class AuthToutiaoRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse userResponse = doGetUserInfo(authToken);
String userResponse = doGetUserInfo(authToken);
JSONObject userProfile = JSONObject.parseObject(userResponse.body());
JSONObject userProfile = JSONObject.parseObject(userResponse);
this.checkResponse(userProfile);
@@ -1,23 +1,24 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.constants.Constants;
import com.xkcoding.http.support.HttpHeader;
import com.xkcoding.http.util.MapUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.GlobalAuthUtils;
import me.zhyd.oauth.utils.UrlBuilder;
import java.util.HashMap;
import java.util.Map;
import static me.zhyd.oauth.config.AuthDefaultSource.TWITTER;
import static me.zhyd.oauth.utils.GlobalAuthUtil.generateTwitterSignature;
import static me.zhyd.oauth.utils.GlobalAuthUtil.urlEncode;
import static me.zhyd.oauth.utils.GlobalAuthUtils.generateTwitterSignature;
import static me.zhyd.oauth.utils.GlobalAuthUtils.urlEncode;
/**
* Twitter登录
@@ -46,19 +47,21 @@ public class AuthTwitterRequest extends AuthDefaultRequest {
public AuthToken getRequestToken() {
String baseUrl = "https://api.twitter.com/oauth/request_token";
Map<String, Object> oauthParams = buildOauthParams();
Map<String, String> oauthParams = buildOauthParams();
oauthParams.put("oauth_callback", config.getRedirectUri());
oauthParams.put("oauth_signature", generateTwitterSignature(oauthParams, "POST", baseUrl, config.getClientSecret(), null));
String header = buildHeader(oauthParams);
HttpResponse requestToken = HttpRequest.post(baseUrl).header("Authorization", header).execute();
checkResponse(requestToken);
Map<String, Object> res = GlobalAuthUtil.parseQueryToMap(requestToken.body());
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Authorization", header);
String requestToken = HttpUtil.post(baseUrl, null, httpHeader);
Map<String, String> res = MapUtil.parseStringToMap(requestToken, false);
return AuthToken.builder()
.oauthToken(res.get("oauth_token").toString())
.oauthTokenSecret(res.get("oauth_token_secret").toString())
.oauthCallbackConfirmed(Boolean.valueOf(res.get("oauth_callback_confirmed").toString()))
.oauthToken(res.get("oauth_token"))
.oauthTokenSecret(res.get("oauth_token_secret"))
.oauthCallbackConfirmed(Boolean.valueOf(res.get("oauth_callback_confirmed")))
.build();
}
@@ -70,45 +73,51 @@ public class AuthTwitterRequest extends AuthDefaultRequest {
*/
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
Map<String, Object> oauthParams = buildOauthParams();
Map<String, String> oauthParams = buildOauthParams();
oauthParams.put("oauth_token", authCallback.getOauthToken());
oauthParams.put("oauth_verifier", authCallback.getOauthVerifier());
oauthParams.put("oauth_signature", generateTwitterSignature(oauthParams, "POST", source.accessToken(), config.getClientSecret(), authCallback.getOauthToken()));
oauthParams.put("oauth_signature", generateTwitterSignature(oauthParams, "POST", source.accessToken(), config.getClientSecret(), authCallback
.getOauthToken()));
String header = buildHeader(oauthParams);
HttpResponse response = HttpRequest.post(source.accessToken())
.header("Authorization", header)
.header("Content-Type", "application/x-www-form-urlencoded")
.form("oauth_verifier", authCallback.getOauthVerifier())
.execute();
checkResponse(response);
Map<String, Object> requestToken = GlobalAuthUtil.parseQueryToMap(response.body());
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Authorization", header);
httpHeader.add(Constants.CONTENT_TYPE, "application/x-www-form-urlencoded");
Map<String, String> form = new HashMap<>(1);
form.put("oauth_verifier", authCallback.getOauthVerifier());
String response = HttpUtil.post(source.accessToken(), form, httpHeader, false);
Map<String, String> requestToken = MapUtil.parseStringToMap(response, false);
return AuthToken.builder()
.oauthToken(requestToken.get("oauth_token").toString())
.oauthTokenSecret(requestToken.get("oauth_token_secret").toString())
.userId(requestToken.get("user_id").toString())
.screenName(requestToken.get("screen_name").toString())
.oauthToken(requestToken.get("oauth_token"))
.oauthTokenSecret(requestToken.get("oauth_token_secret"))
.userId(requestToken.get("user_id"))
.screenName(requestToken.get("screen_name"))
.build();
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
Map<String, Object> queryParams = new HashMap<>();
Map<String, String> queryParams = new HashMap<>();
queryParams.put("user_id", authToken.getUserId());
queryParams.put("screen_name", authToken.getScreenName());
queryParams.put("include_entities", true);
queryParams.put("include_entities", Boolean.toString(true));
Map<String, Object> oauthParams = buildOauthParams();
Map<String, String> oauthParams = buildOauthParams();
oauthParams.put("oauth_token", authToken.getOauthToken());
Map<String, Object> params = new HashMap<>(oauthParams);
Map<String, String> params = new HashMap<>(oauthParams);
params.putAll(queryParams);
oauthParams.put("oauth_signature", generateTwitterSignature(params, "GET", source.userInfo(), config.getClientSecret(), authToken.getOauthTokenSecret()));
oauthParams.put("oauth_signature", generateTwitterSignature(params, "GET", source.userInfo(), config.getClientSecret(), authToken
.getOauthTokenSecret()));
String header = buildHeader(oauthParams);
HttpResponse response = HttpRequest.get(userInfoUrl(authToken)).header("Authorization", header).execute();
checkResponse(response);
JSONObject userInfo = JSONObject.parseObject(response.body());
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Authorization", header);
String response = HttpUtil.get(userInfoUrl(authToken), null, httpHeader, false);
JSONObject userInfo = JSONObject.parseObject(response);
return AuthUser.builder()
.uuid(userInfo.getString("id_str"))
@@ -132,35 +141,26 @@ public class AuthTwitterRequest extends AuthDefaultRequest {
.build();
}
private Map<String, Object> buildOauthParams() {
Map<String, Object> params = new HashMap<>();
private Map<String, String> buildOauthParams() {
Map<String, String> params = new HashMap<>(5);
params.put("oauth_consumer_key", config.getClientId());
params.put("oauth_nonce", GlobalAuthUtil.generateNonce(32));
params.put("oauth_nonce", GlobalAuthUtils.generateNonce(32));
params.put("oauth_signature_method", "HMAC-SHA1");
params.put("oauth_timestamp", GlobalAuthUtil.getTimestamp());
params.put("oauth_timestamp", GlobalAuthUtils.getTimestamp());
params.put("oauth_version", "1.0");
return params;
}
private String buildHeader(Map<String, Object> oauthParams) {
private String buildHeader(Map<String, String> oauthParams) {
final StringBuilder sb = new StringBuilder(PREAMBLE);
for (Map.Entry<String, Object> param : oauthParams.entrySet()) {
for (Map.Entry<String, String> param : oauthParams.entrySet()) {
if (sb.length() > PREAMBLE.length()) {
sb.append(", ");
}
sb.append(param.getKey())
.append("=\"")
.append(urlEncode(param.getValue().toString()))
.append('"');
sb.append(param.getKey()).append("=\"").append(urlEncode(param.getValue())).append('"');
}
return sb.toString();
}
private void checkResponse(HttpResponse response) {
if (!response.isOk()) {
throw new AuthException(response.body());
}
}
}
@@ -1,8 +1,7 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -39,7 +38,7 @@ public class AuthWeChatEnterpriseRequest extends AuthDefaultRequest {
*/
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doGetAuthorizationCode(accessTokenUrl(authCallback.getCode()));
String response = doGetAuthorizationCode(accessTokenUrl(authCallback.getCode()));
JSONObject object = this.checkResponse(response);
@@ -52,19 +51,17 @@ public class AuthWeChatEnterpriseRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
String response = doGetUserInfo(authToken);
JSONObject object = this.checkResponse(response);
// 返回 OpenId 或其他,均代表非当前企业用户,不支持
if (!object.containsKey("UserId")) {
throw new AuthException(AuthResponseStatus.UNIDENTIFIED_PLATFORM);
throw new AuthException(AuthResponseStatus.UNIDENTIFIED_PLATFORM, source);
}
String userId = object.getString("UserId");
HttpResponse userDetailResponse = getUserDetail(authToken.getAccessToken(), userId);
String userDetailResponse = getUserDetail(authToken.getAccessToken(), userId);
JSONObject userDetail = this.checkResponse(userDetailResponse);
String gender = getRealGender(userDetail);
return AuthUser.builder()
.username(userDetail.getString("name"))
.nickname(userDetail.getString("alias"))
@@ -72,7 +69,7 @@ public class AuthWeChatEnterpriseRequest extends AuthDefaultRequest {
.location(userDetail.getString("address"))
.email(userDetail.getString("email"))
.uuid(userId)
.gender(AuthUserGender.getRealGender(gender))
.gender(AuthUserGender.getWechatRealGender(userDetail.getString("gender")))
.token(authToken)
.source(source.toString())
.build();
@@ -84,30 +81,16 @@ public class AuthWeChatEnterpriseRequest extends AuthDefaultRequest {
* @param response 请求结果
* @return 如果请求结果正常,则返回JSONObject
*/
private JSONObject checkResponse(HttpResponse response) {
JSONObject object = JSONObject.parseObject(response.body());
private JSONObject checkResponse(String response) {
JSONObject object = JSONObject.parseObject(response);
if (object.containsKey("errcode") && object.getIntValue("errcode") != 0) {
throw new AuthException(object.getIntValue("errcode"), object.getString("errmsg"));
throw new AuthException(object.getString("errmsg"), source);
}
return object;
}
/**
* 获取用户的实际性别,0表示未定义,1表示男性,2表示女性
*
* @param userDetail 用户详情
* @return 用户性别
*/
private String getRealGender(JSONObject userDetail) {
int gender = userDetail.getIntValue("gender");
if (AuthUserGender.MALE.getCode() == gender) {
return "1";
}
return 2 == gender ? "0" : null;
}
/**
* 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
*
@@ -160,12 +143,12 @@ public class AuthWeChatEnterpriseRequest extends AuthDefaultRequest {
* @param userId 企业内用户id
* @return 用户详情
*/
private HttpResponse getUserDetail(String accessToken, String userId) {
private String getUserDetail(String accessToken, String userId) {
String userDetailUrl = UrlBuilder.fromBaseUrl("https://qyapi.weixin.qq.com/cgi-bin/user/get")
.queryParam("access_token", accessToken)
.queryParam("userid", userId)
.build();
return HttpRequest.get(userDetailUrl).execute();
return HttpUtil.get(userDetailUrl);
}
}
@@ -0,0 +1,174 @@
package me.zhyd.oauth.request;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtils;
import me.zhyd.oauth.utils.UrlBuilder;
/**
* 微信公众平台登录
*
* @author yangkai.shen (https://xkcoding.com)
* @since 1.1.0
*/
public class AuthWeChatMpRequest extends AuthDefaultRequest {
public AuthWeChatMpRequest(AuthConfig config) {
super(config, AuthDefaultSource.WECHAT_MP);
}
public AuthWeChatMpRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.WECHAT_MP, authStateCache);
}
/**
* 微信的特殊性,此时返回的信息同时包含 openid 和 access_token
*
* @param authCallback 回调返回的参数
* @return 所有信息
*/
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
return this.getToken(accessTokenUrl(authCallback.getCode()));
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
String openId = authToken.getOpenId();
String response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
String location = String.format("%s-%s-%s", object.getString("country"), object.getString("province"), object.getString("city"));
if (object.containsKey("unionid")) {
authToken.setUnionId(object.getString("unionid"));
}
return AuthUser.builder()
.username(object.getString("nickname"))
.nickname(object.getString("nickname"))
.avatar(object.getString("headimgurl"))
.location(location)
.uuid(openId)
.gender(AuthUserGender.getWechatRealGender(object.getString("sex")))
.token(authToken)
.source(source.toString())
.build();
}
@Override
public AuthResponse refresh(AuthToken oldToken) {
return AuthResponse.builder()
.code(AuthResponseStatus.SUCCESS.getCode())
.data(this.getToken(refreshTokenUrl(oldToken.getRefreshToken())))
.build();
}
/**
* 检查响应内容是否正确
*
* @param object 请求响应内容
*/
private void checkResponse(JSONObject object) {
if (object.containsKey("errcode")) {
throw new AuthException(object.getIntValue("errcode"), object.getString("errmsg"));
}
}
/**
* 获取token,适用于获取access_token和刷新token
*
* @param accessTokenUrl 实际请求token的地址
* @return token对象
*/
private AuthToken getToken(String accessTokenUrl) {
String response = HttpUtil.get(accessTokenUrl);
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
.refreshToken(accessTokenObject.getString("refresh_token"))
.expireIn(accessTokenObject.getIntValue("expires_in"))
.openId(accessTokenObject.getString("openid"))
.scope(accessTokenObject.getString("scope"))
.build();
}
/**
* 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
*
* @param state state 验证授权流程的参数,可以防止csrf
* @return 返回授权地址
* @since 1.9.3
*/
@Override
public String authorize(String state) {
return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("appid", config.getClientId())
.queryParam("redirect_uri", GlobalAuthUtils.urlEncode(config.getRedirectUri()))
.queryParam("response_type", "code")
.queryParam("scope", "snsapi_userinfo")
.queryParam("state", getRealState(state).concat("#wechat_redirect"))
.build();
}
/**
* 返回获取accessToken的url
*
* @param code 授权码
* @return 返回获取accessToken的url
*/
@Override
protected String accessTokenUrl(String code) {
return UrlBuilder.fromBaseUrl(source.accessToken())
.queryParam("appid", config.getClientId())
.queryParam("secret", config.getClientSecret())
.queryParam("code", code)
.queryParam("grant_type", "authorization_code")
.build();
}
/**
* 返回获取userInfo的url
*
* @param authToken 用户授权后的token
* @return 返回获取userInfo的url
*/
@Override
protected String userInfoUrl(AuthToken authToken) {
return UrlBuilder.fromBaseUrl(source.userInfo())
.queryParam("access_token", authToken.getAccessToken())
.queryParam("openid", authToken.getOpenId())
.queryParam("lang", "zh_CN")
.build();
}
/**
* 返回获取userInfo的url
*
* @param refreshToken getAccessToken方法返回的refreshToken
* @return 返回获取userInfo的url
*/
@Override
protected String refreshTokenUrl(String refreshToken) {
return UrlBuilder.fromBaseUrl(source.refresh())
.queryParam("appid", config.getClientId())
.queryParam("grant_type", "refresh_token")
.queryParam("refresh_token", refreshToken)
.build();
}
}
@@ -1,8 +1,7 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
@@ -16,18 +15,18 @@ import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.UrlBuilder;
/**
* 微信登录
* 微信开放平台登录
*
* @author yangkai.shen (https://xkcoding.com)
* @since 1.1.0
*/
public class AuthWeChatRequest extends AuthDefaultRequest {
public AuthWeChatRequest(AuthConfig config) {
super(config, AuthDefaultSource.WECHAT);
public class AuthWeChatOpenRequest extends AuthDefaultRequest {
public AuthWeChatOpenRequest(AuthConfig config) {
super(config, AuthDefaultSource.WECHAT_OPEN);
}
public AuthWeChatRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.WECHAT, authStateCache);
public AuthWeChatOpenRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.WECHAT_OPEN, authStateCache);
}
/**
@@ -45,8 +44,8 @@ public class AuthWeChatRequest extends AuthDefaultRequest {
protected AuthUser getUserInfo(AuthToken authToken) {
String openId = authToken.getOpenId();
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
String response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response);
this.checkResponse(object);
@@ -62,7 +61,7 @@ public class AuthWeChatRequest extends AuthDefaultRequest {
.avatar(object.getString("headimgurl"))
.location(location)
.uuid(openId)
.gender(AuthUserGender.getRealGender(object.getString("sex")))
.gender(AuthUserGender.getWechatRealGender(object.getString("sex")))
.token(authToken)
.source(source.toString())
.build();
@@ -94,8 +93,8 @@ public class AuthWeChatRequest extends AuthDefaultRequest {
* @return token对象
*/
private AuthToken getToken(String accessTokenUrl) {
HttpResponse response = HttpRequest.get(accessTokenUrl).execute();
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
String response = HttpUtil.get(accessTokenUrl);
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
@@ -1,14 +1,16 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.support.HttpHeader;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.IpUtils;
@@ -34,9 +36,8 @@ public class AuthWeiboRequest extends AuthDefaultRequest {
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
String accessTokenStr = response.body();
JSONObject accessTokenObject = JSONObject.parseObject(accessTokenStr);
String response = doPostAuthorizationCode(authCallback.getCode());
JSONObject accessTokenObject = JSONObject.parseObject(response);
if (accessTokenObject.containsKey("error")) {
throw new AuthException(accessTokenObject.getString("error_description"));
}
@@ -53,11 +54,11 @@ public class AuthWeiboRequest extends AuthDefaultRequest {
String accessToken = authToken.getAccessToken();
String uid = authToken.getUid();
String oauthParam = String.format("uid=%s&access_token=%s", uid, accessToken);
HttpResponse response = HttpRequest.get(userInfoUrl(authToken))
.header("Authorization", "OAuth2 " + oauthParam)
.header("API-RemoteIP", IpUtils.getLocalIp())
.execute();
String userInfo = response.body();
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Authorization", "OAuth2 " + oauthParam);
httpHeader.add("API-RemoteIP", IpUtils.getLocalIp());
String userInfo = HttpUtil.get(userInfoUrl(authToken), null, httpHeader, false);
JSONObject object = JSONObject.parseObject(userInfo);
if (object.containsKey("error")) {
throw new AuthException(object.getString("error"));
@@ -90,4 +91,19 @@ public class AuthWeiboRequest extends AuthDefaultRequest {
.queryParam("uid", authToken.getUid())
.build();
}
@Override
public AuthResponse revoke(AuthToken authToken) {
String response = doGetRevoke(authToken);
JSONObject object = JSONObject.parseObject(response);
if (object.containsKey("error")) {
return AuthResponse.builder()
.code(AuthResponseStatus.FAILURE.getCode())
.msg(object.getString("error"))
.build();
}
// 返回 result = true 表示取消授权成功,否则失败
AuthResponseStatus status = object.getBooleanValue("result") ? AuthResponseStatus.SUCCESS : AuthResponseStatus.FAILURE;
return AuthResponse.builder().code(status.getCode()).msg(status.getMsg()).build();
}
}
@@ -1,5 +1,6 @@
package me.zhyd.oauth.utils;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.config.AuthSource;
@@ -31,7 +32,7 @@ public class AuthChecker {
if (isSupported && AuthDefaultSource.STACK_OVERFLOW == source) {
isSupported = StringUtils.isNotEmpty(config.getStackOverflowKey());
}
if (isSupported && AuthDefaultSource.WECHAT_ENTERPRISE == source){
if (isSupported && AuthDefaultSource.WECHAT_ENTERPRISE == source) {
isSupported = StringUtils.isNotEmpty(config.getAgentId());
}
return isSupported;
@@ -46,16 +47,18 @@ public class AuthChecker {
*/
public static void checkConfig(AuthConfig config, AuthSource source) {
String redirectUri = config.getRedirectUri();
if (!GlobalAuthUtil.isHttpProtocol(redirectUri) && !GlobalAuthUtil.isHttpsProtocol(redirectUri)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI);
if (!GlobalAuthUtils.isHttpProtocol(redirectUri) && !GlobalAuthUtils.isHttpsProtocol(redirectUri)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI, source);
}
// facebook的回调地址必须为https的链接
if (AuthDefaultSource.FACEBOOK == source && !GlobalAuthUtil.isHttpsProtocol(redirectUri)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI);
if (AuthDefaultSource.FACEBOOK == source && !GlobalAuthUtils.isHttpsProtocol(redirectUri)) {
// Facebook's redirect uri must use the HTTPS protocol
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI, source);
}
// 支付宝在创建回调地址时,不允许使用localhost或者127.0.0.1
if (AuthDefaultSource.ALIPAY == source && GlobalAuthUtil.isLocalHost(redirectUri)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI);
if (AuthDefaultSource.ALIPAY == source && GlobalAuthUtils.isLocalHost(redirectUri)) {
// The redirect uri of alipay is forbidden to use localhost or 127.0.0.1
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI, source);
}
}
@@ -76,7 +79,24 @@ public class AuthChecker {
code = callback.getAuthorization_code();
}
if (StringUtils.isEmpty(code)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_CODE);
throw new AuthException(AuthResponseStatus.ILLEGAL_CODE, source);
}
}
/**
* 校验回调传回的{@code state},为空或者不存在
* <p>
* {@code state}不存在的情况只有两种:
* 1. {@code state}已使用,被正常清除
* 2. {@code state}为前端伪造,本身就不存在
*
* @param state {@code state}一定不为空
* @param source {@code source}当前授权平台
* @param authStateCache {@code authStateCache} state缓存实现
*/
public static void checkState(String state, AuthSource source, AuthStateCache authStateCache) {
if (StringUtils.isEmpty(state) || !authStateCache.containsKey(state)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_STATUS, source);
}
}
}
@@ -0,0 +1,197 @@
package me.zhyd.oauth.utils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* Base64编码
*
* @author looly
* @since 3.2.0
*/
public class Base64Utils {
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
/**
* 标准编码表
*/
private static final byte[] STANDARD_ENCODE_TABLE = { //
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', //
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', //
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', //
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', //
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', //
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', //
'w', 'x', 'y', 'z', '0', '1', '2', '3', //
'4', '5', '6', '7', '8', '9', '+', '/' //
};
/**
* URL安全的编码表,将 + 和 / 替换为 - 和 _
*/
private static final byte[] URL_SAFE_ENCODE_TABLE = { //
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', //
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', //
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', //
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', //
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', //
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', //
'w', 'x', 'y', 'z', '0', '1', '2', '3', //
'4', '5', '6', '7', '8', '9', '-', '_' //
};
// -------------------------------------------------------------------- encode
/**
* 编码为Base64,非URL安全的
*
* @param arr 被编码的数组
* @param lineSep 在76个char之后是CRLF还是EOF
* @return 编码后的bytes
*/
public static byte[] encode(byte[] arr, boolean lineSep) {
return encode(arr, lineSep, false);
}
/**
* 编码为Base64URL安全的
*
* @param arr 被编码的数组
* @param lineSep 在76个char之后是CRLF还是EOF
* @return 编码后的bytes
* @since 3.0.6
*/
public static byte[] encodeUrlSafe(byte[] arr, boolean lineSep) {
return encode(arr, lineSep, true);
}
/**
* base64编码
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
*/
public static String encode(CharSequence source) {
return encode(source, DEFAULT_CHARSET);
}
/**
* base64编码,URL安全
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
* @since 3.0.6
*/
public static String encodeUrlSafe(CharSequence source) {
return encodeUrlSafe(source, DEFAULT_CHARSET);
}
/**
* base64编码
*
* @param source 被编码的base64字符串
* @param charset 字符集
* @return 被加密后的字符串
*/
public static String encode(CharSequence source, Charset charset) {
return encode(StringUtils.bytes(source, charset));
}
/**
* base64编码,URL安全的
*
* @param source 被编码的base64字符串
* @param charset 字符集
* @return 被加密后的字符串
* @since 3.0.6
*/
public static String encodeUrlSafe(CharSequence source, Charset charset) {
return encodeUrlSafe(StringUtils.bytes(source, charset));
}
/**
* base64编码
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
*/
public static String encode(byte[] source) {
return StringUtils.str(encode(source, false), DEFAULT_CHARSET);
}
/**
* base64编码,URL安全的
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
* @since 3.0.6
*/
public static String encodeUrlSafe(byte[] source) {
return StringUtils.str(encodeUrlSafe(source, false), DEFAULT_CHARSET);
}
/**
* 编码为Base64<br>
* 如果isMultiLine为<code>true</code>,则每76个字符一个换行符,否则在一行显示
*
* @param arr 被编码的数组
* @param isMultiLine 在76个char之后是CRLF还是EOF
* @param isUrlSafe 是否使用URL安全字符,一般为<code>false</code>
* @return 编码后的bytes
*/
public static byte[] encode(byte[] arr, boolean isMultiLine, boolean isUrlSafe) {
if (null == arr) {
return null;
}
int len = arr.length;
if (len == 0) {
return new byte[0];
}
int evenlen = (len / 3) * 3;
int cnt = ((len - 1) / 3 + 1) << 2;
int destlen = cnt + (isMultiLine ? (cnt - 1) / 76 << 1 : 0);
byte[] dest = new byte[destlen];
byte[] encodeTable = isUrlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE;
for (int s = 0, d = 0, cc = 0; s < evenlen; ) {
int i = (arr[s++] & 0xff) << 16 | (arr[s++] & 0xff) << 8 | (arr[s++] & 0xff);
dest[d++] = encodeTable[(i >>> 18) & 0x3f];
dest[d++] = encodeTable[(i >>> 12) & 0x3f];
dest[d++] = encodeTable[(i >>> 6) & 0x3f];
dest[d++] = encodeTable[i & 0x3f];
if (isMultiLine && ++cc == 19 && d < destlen - 2) {
dest[d++] = '\r';
dest[d++] = '\n';
cc = 0;
}
}
int left = len - evenlen;// 剩余位数
if (left > 0) {
int i = ((arr[evenlen] & 0xff) << 10) | (left == 2 ? ((arr[len - 1] & 0xff) << 2) : 0);
dest[destlen - 4] = encodeTable[i >> 12];
dest[destlen - 3] = encodeTable[(i >>> 6) & 0x3f];
if (isUrlSafe) {
// 在URL Safe模式下,=为URL中的关键字符,不需要补充。空余的byte位要去掉。
int urlSafeLen = destlen - 2;
if (2 == left) {
dest[destlen - 2] = encodeTable[i & 0x3f];
urlSafeLen += 1;
}
byte[] urlSafeDest = new byte[urlSafeLen];
System.arraycopy(dest, 0, urlSafeDest, 0, urlSafeLen);
return urlSafeDest;
} else {
dest[destlen - 2] = (left == 2) ? encodeTable[i & 0x3f] : (byte) '=';
dest[destlen - 1] = '=';
}
}
return dest;
}
}
@@ -1,9 +1,5 @@
package me.zhyd.oauth.utils;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import me.zhyd.oauth.exception.AuthException;
@@ -17,13 +13,7 @@ import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
import java.util.*;
/**
* 全局的工具类
@@ -31,7 +21,7 @@ import java.util.TreeMap;
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @since 1.0.0
*/
public class GlobalAuthUtil {
public class GlobalAuthUtils {
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
private static final String HMAC_SHA1 = "HmacSHA1";
private static final String HMAC_SHA_256 = "HmacSHA256";
@@ -45,7 +35,7 @@ public class GlobalAuthUtil {
*/
public static String generateDingTalkSignature(String secretKey, String timestamp) {
byte[] signData = sign(secretKey.getBytes(DEFAULT_ENCODING), timestamp.getBytes(DEFAULT_ENCODING), HMAC_SHA_256);
return urlEncode(new String(Base64.encode(signData, false)));
return urlEncode(new String(Base64Utils.encode(signData, false)));
}
/**
@@ -79,7 +69,7 @@ public class GlobalAuthUtil {
return "";
}
try {
String encoded = URLEncoder.encode(value, GlobalAuthUtil.DEFAULT_ENCODING.displayName());
String encoded = URLEncoder.encode(value, GlobalAuthUtils.DEFAULT_ENCODING.displayName());
return encoded.replace("+", "%20").replace("*", "%2A").replace("~", "%7E").replace("/", "%2F");
} catch (UnsupportedEncodingException e) {
throw new AuthException("Failed To Encode Uri", e);
@@ -98,7 +88,7 @@ public class GlobalAuthUtil {
return "";
}
try {
return URLDecoder.decode(value, GlobalAuthUtil.DEFAULT_ENCODING.displayName());
return URLDecoder.decode(value, GlobalAuthUtils.DEFAULT_ENCODING.displayName());
} catch (UnsupportedEncodingException e) {
throw new AuthException("Failed To Decode Uri", e);
}
@@ -111,13 +101,13 @@ public class GlobalAuthUtil {
* @return map
*/
public static Map<String, String> parseStringToMap(String accessTokenStr) {
Map<String, String> res = new HashMap<>();
Map<String, String> res = new HashMap<>(6);
if (accessTokenStr.contains("&")) {
String[] fields = accessTokenStr.split("&");
for (String field : fields) {
if (field.contains("=")) {
String[] keyValue = field.split("=");
res.put(GlobalAuthUtil.urlDecode(keyValue[0]), keyValue.length == 2 ? GlobalAuthUtil.urlDecode(keyValue[1]) : null);
res.put(GlobalAuthUtils.urlDecode(keyValue[0]), keyValue.length == 2 ? GlobalAuthUtils.urlDecode(keyValue[1]) : null);
}
}
}
@@ -131,29 +121,16 @@ public class GlobalAuthUtil {
* @param encode 是否转码
* @return str
*/
public static String parseMapToString(Map<String, Object> params, boolean encode) {
public static String parseMapToString(Map<String, String> params, boolean encode) {
List<String> paramList = new ArrayList<>();
params.forEach((k, v) -> {
if (ObjectUtil.isNull(v)) {
if (null == v) {
paramList.add(k + "=");
} else {
String valueString = v.toString();
paramList.add(k + "=" + (encode ? urlEncode(valueString) : valueString));
paramList.add(k + "=" + (encode ? urlEncode(v) : v));
}
});
return CollUtil.join(paramList, "&");
}
/**
* 将url的参数列表转换成map
*
* @param url 待转换的url
* @return map
*/
public static Map<String, Object> parseQueryToMap(String url) {
Map<String, Object> paramMap = new HashMap<>();
HttpUtil.decodeParamMap(url, "UTF-8").forEach(paramMap::put);
return paramMap;
return String.join("&", paramList);
}
/**
@@ -230,9 +207,9 @@ public class GlobalAuthUtil {
* @param tokenSecret oauth token secret
* @return BASE64 encoded signature string
*/
public static String generateTwitterSignature(Map<String, Object> params, String method, String baseUrl, String apiSecret, String tokenSecret) {
TreeMap<String, Object> map = new TreeMap<>();
for (Map.Entry<String, Object> e : params.entrySet()) {
public static String generateTwitterSignature(Map<String, String> params, String method, String baseUrl, String apiSecret, String tokenSecret) {
TreeMap<String, String> map = new TreeMap<>();
for (Map.Entry<String, String> e : params.entrySet()) {
map.put(urlEncode(e.getKey()), e.getValue());
}
String str = parseMapToString(map, true);
@@ -240,7 +217,7 @@ public class GlobalAuthUtil {
String signKey = apiSecret + "&" + (StringUtils.isEmpty(tokenSecret) ? "" : tokenSecret);
byte[] signature = sign(signKey.getBytes(DEFAULT_ENCODING), baseStr.getBytes(DEFAULT_ENCODING), HMAC_SHA1);
return new String(Base64.encode(signature, false));
return new String(Base64Utils.encode(signature, false));
}
/**
@@ -1,7 +1,6 @@
package me.zhyd.oauth.utils;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ThreadLocalRandom;
import java.nio.charset.Charset;
/**
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
@@ -36,4 +35,40 @@ public class StringUtils {
return str.concat(appendStr);
}
/**
* 编码字符串
*
* @param str 字符串
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
* @return 编码后的字节码
*/
public static byte[] bytes(CharSequence str, Charset charset) {
if (str == null) {
return null;
}
if (null == charset) {
return str.toString().getBytes();
}
return str.toString().getBytes(charset);
}
/**
* 解码字节码
*
* @param data 字符串
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
* @return 解码后的字符串
*/
public static String str(byte[] data, Charset charset) {
if (data == null) {
return null;
}
if (null == charset) {
return new String(data);
}
return new String(data, charset);
}
}

Some files were not shown because too many files have changed in this diff Show More