Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
XKZJ_WCL
JustAuth
提交
665daa37
J
JustAuth
项目概览
XKZJ_WCL
/
JustAuth
与 Fork 源项目一致
Fork自
justauth / JustAuth
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
JustAuth
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
665daa37
编写于
8月 05, 2019
作者:
智布道
👁
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
📝
集成华为
上级
576402ee
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
300 addition
and
3 deletion
+300
-3
docs/update.md
docs/update.md
+5
-0
src/main/java/me/zhyd/oauth/config/AuthSource.java
src/main/java/me/zhyd/oauth/config/AuthSource.java
+26
-0
src/main/java/me/zhyd/oauth/model/AuthCallback.java
src/main/java/me/zhyd/oauth/model/AuthCallback.java
+7
-0
src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java
src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java
+1
-1
src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java
src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java
+194
-0
src/main/java/me/zhyd/oauth/utils/AuthChecker.java
src/main/java/me/zhyd/oauth/utils/AuthChecker.java
+12
-2
src/test/java/me/zhyd/oauth/AuthRequestTest.java
src/test/java/me/zhyd/oauth/AuthRequestTest.java
+14
-0
src/test/java/me/zhyd/oauth/sdk/ThirdPartSdkTest.java
src/test/java/me/zhyd/oauth/sdk/ThirdPartSdkTest.java
+41
-0
未找到文件。
docs/update.md
浏览文件 @
665daa37
## v1.9.6
### 2019/08/05
-
集成华为登录
-
修改
`AuthChecker#checkCode`
方法,对于不同平台使用不同参数接受code的情况统一做处理
### 2019/08/03
合并github上
[
xkcoding
](
https://github.com/xkcoding
)
的
[
pr#32
](
https://github.com/zhangyd-c/JustAuth/pull/32
)
,抽取 cache 接口,方便用户自行集成 cache
...
...
src/main/java/me/zhyd/oauth/config/AuthSource.java
浏览文件 @
665daa37
...
...
@@ -518,6 +518,32 @@ public enum AuthSource {
public
String
userInfo
()
{
return
"https://api.stackexchange.com/2.2/me"
;
}
},
/**
* 华为
* @since 1.9.6
*/
HUAWEI
{
@Override
public
String
authorize
()
{
return
"https://oauth-login.cloud.huawei.com/oauth2/v2/authorize"
;
}
@Override
public
String
accessToken
()
{
return
"https://oauth-login.cloud.huawei.com/oauth2/v2/token"
;
}
@Override
public
String
userInfo
()
{
return
"https://api.vmall.com/rest.php"
;
}
@Override
public
String
refresh
()
{
return
"https://oauth-login.cloud.huawei.com/oauth2/v2/token"
;
}
};
/**
...
...
src/main/java/me/zhyd/oauth/model/AuthCallback.java
浏览文件 @
665daa37
...
...
@@ -27,4 +27,11 @@ public class AuthCallback {
* 访问AuthorizeUrl后回调时带的参数state,用于和请求AuthorizeUrl前的state比较,防止CSRF攻击
*/
private
String
state
;
/**
* 华为授权登录接受code的参数名
*
* @since 1.9.6
*/
private
String
authorization_code
;
}
src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java
浏览文件 @
665daa37
...
...
@@ -74,7 +74,7 @@ public abstract class AuthDefaultRequest implements AuthRequest {
@Override
public
AuthResponse
login
(
AuthCallback
authCallback
)
{
try
{
AuthChecker
.
checkCode
(
source
==
AuthSource
.
ALIPAY
?
authCallback
.
getAuth_code
()
:
authCallback
.
getCode
()
);
AuthChecker
.
checkCode
(
source
,
authCallback
);
this
.
checkState
(
authCallback
.
getState
());
AuthToken
authToken
=
this
.
getAccessToken
(
authCallback
);
...
...
src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java
0 → 100644
浏览文件 @
665daa37
package
me.zhyd.oauth.request
;
import
cn.hutool.http.HttpRequest
;
import
cn.hutool.http.HttpResponse
;
import
com.alibaba.fastjson.JSONObject
;
import
me.zhyd.oauth.cache.AuthStateCache
;
import
me.zhyd.oauth.config.AuthConfig
;
import
me.zhyd.oauth.config.AuthSource
;
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.UrlBuilder
;
import
static
me
.
zhyd
.
oauth
.
enums
.
AuthResponseStatus
.
SUCCESS
;
/**
* 华为授权登录
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0
* @since 1.9.6
*/
public
class
AuthHuaweiRequest
extends
AuthDefaultRequest
{
public
AuthHuaweiRequest
(
AuthConfig
config
)
{
super
(
config
,
AuthSource
.
HUAWEI
);
}
public
AuthHuaweiRequest
(
AuthConfig
config
,
AuthStateCache
authStateCache
)
{
super
(
config
,
AuthSource
.
HUAWEI
,
authStateCache
);
}
/**
* 获取access token
*
* @param authCallback 授权成功后的回调参数
* @return token
* @see AuthDefaultRequest#authorize()
* @see AuthDefaultRequest#authorize(String)
*/
@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
);
}
/**
* 使用token换取用户信息
*
* @param authToken token信息
* @return 用户信息
* @see AuthDefaultRequest#getAccessToken(AuthCallback)
*/
@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
());
this
.
checkResponse
(
object
);
AuthUserGender
gender
=
getRealGender
(
object
);
return
AuthUser
.
builder
()
.
uuid
(
object
.
getString
(
"userID"
))
.
username
(
object
.
getString
(
"userName"
))
.
nickname
(
object
.
getString
(
"userName"
))
.
gender
(
gender
)
.
avatar
(
object
.
getString
(
"headPictureURL"
))
.
build
();
}
/**
* 刷新access token (续期)
*
* @param authToken 登录成功后返回的Token信息
* @return AuthResponse
*/
@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
();
}
private
AuthToken
getAuthToken
(
HttpRequest
request
)
{
HttpResponse
response
=
request
.
execute
();
JSONObject
object
=
JSONObject
.
parseObject
(
response
.
body
());
this
.
checkResponse
(
object
);
return
AuthToken
.
builder
()
.
accessToken
(
object
.
getString
(
"access_token"
))
.
expireIn
(
object
.
getIntValue
(
"expires_in"
))
.
refreshToken
(
object
.
getString
(
"refresh_token"
))
.
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
(
"response_type"
,
"code"
)
.
queryParam
(
"client_id"
,
config
.
getClientId
())
.
queryParam
(
"redirect_uri"
,
config
.
getRedirectUri
())
.
queryParam
(
"access_type"
,
"offline"
)
.
queryParam
(
"scope"
,
"https%3A%2F%2Fwww.huawei.com%2Fauth%2Faccount%2Fbase.profile"
)
.
queryParam
(
"state"
,
getRealState
(
state
))
.
build
();
}
/**
* 返回获取accessToken的url
*
* @param code 授权码
* @return 返回获取accessToken的url
*/
@Override
protected
String
accessTokenUrl
(
String
code
)
{
return
UrlBuilder
.
fromBaseUrl
(
source
.
accessToken
())
.
queryParam
(
"grant_type"
,
"authorization_code"
)
.
queryParam
(
"code"
,
code
)
.
queryParam
(
"client_id"
,
config
.
getClientId
())
.
queryParam
(
"client_secret"
,
config
.
getClientSecret
())
.
queryParam
(
"redirect_uri"
,
config
.
getRedirectUri
())
.
build
();
}
/**
* 返回获取userInfo的url
*
* @param authToken token
* @return 返回获取userInfo的url
*/
@Override
protected
String
userInfoUrl
(
AuthToken
authToken
)
{
return
UrlBuilder
.
fromBaseUrl
(
source
.
userInfo
())
.
queryParam
(
"nsp_ts"
,
System
.
currentTimeMillis
())
.
queryParam
(
"access_token"
,
authToken
.
getAccessToken
())
.
queryParam
(
"nsp_fmt"
,
"JS"
)
.
queryParam
(
"nsp_svc"
,
"OpenUP.User.getInfo"
)
.
build
();
}
/**
* 获取用户的实际性别。华为系统中,用户的性别:1表示女,0表示男
*
* @param object obj
* @return AuthUserGender
*/
private
AuthUserGender
getRealGender
(
JSONObject
object
)
{
int
genderCodeInt
=
object
.
getIntValue
(
"gender"
);
String
genderCode
=
genderCodeInt
==
1
?
"0"
:
(
genderCodeInt
==
0
)
?
"1"
:
genderCodeInt
+
""
;
return
AuthUserGender
.
getRealGender
(
genderCode
);
}
/**
* 校验响应结果
*
* @param object 接口返回的结果
*/
private
void
checkResponse
(
JSONObject
object
)
{
if
(
object
.
containsKey
(
"error"
))
{
if
(!
object
.
containsKey
(
"sub_error"
)
&&
!
object
.
containsKey
(
"error_description"
))
{
throw
new
AuthException
(
object
.
getString
(
"error"
));
}
throw
new
AuthException
(
object
.
getString
(
"sub_error"
)
+
":"
+
object
.
getString
(
"error_description"
));
}
}
}
src/main/java/me/zhyd/oauth/utils/AuthChecker.java
浏览文件 @
665daa37
...
...
@@ -4,6 +4,7 @@ import me.zhyd.oauth.config.AuthConfig;
import
me.zhyd.oauth.config.AuthSource
;
import
me.zhyd.oauth.enums.AuthResponseStatus
;
import
me.zhyd.oauth.exception.AuthException
;
import
me.zhyd.oauth.model.AuthCallback
;
/**
* 授权配置类的校验器
...
...
@@ -56,11 +57,20 @@ public class AuthChecker {
/**
* 校验回调传回的code
* <p>
* {@code v1.9.6}版本中改为传入{@code source}和{@code callback},对于不同平台使用不同参数接受code的情况统一做处理
*
* @param code 回调时传回的code
* @param source 当前授权平台
* @param callback 从第三方授权回调回来时传入的参数集合
* @since 1.8.0
*/
public
static
void
checkCode
(
String
code
)
{
public
static
void
checkCode
(
AuthSource
source
,
AuthCallback
callback
)
{
String
code
=
callback
.
getCode
();
if
(
source
==
AuthSource
.
ALIPAY
)
{
code
=
callback
.
getAuth_code
();
}
else
if
(
source
==
AuthSource
.
HUAWEI
)
{
code
=
callback
.
getAuthorization_code
();
}
if
(
StringUtils
.
isEmpty
(
code
))
{
throw
new
AuthException
(
AuthResponseStatus
.
ILLEGAL_CODE
);
}
...
...
src/test/java/me/zhyd/oauth/AuthRequestTest.java
浏览文件 @
665daa37
...
...
@@ -277,4 +277,18 @@ public class AuthRequestTest {
// 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse
login
=
authRequest
.
login
(
new
AuthCallback
());
}
@Test
public
void
huaweiTest
()
{
AuthRequest
authRequest
=
new
AuthHuaweiRequest
(
AuthConfig
.
builder
()
.
clientId
(
"clientId"
)
.
clientSecret
(
"clientSecret"
)
.
redirectUri
(
"redirectUri"
)
.
build
());
// 返回授权页面,可自行跳转
authRequest
.
authorize
(
"state"
);
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
// 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse
login
=
authRequest
.
login
(
new
AuthCallback
());
}
}
src/test/java/me/zhyd/oauth/sdk/ThirdPartSdkTest.java
0 → 100644
浏览文件 @
665daa37
package
me.zhyd.oauth.sdk
;
import
cn.hutool.http.HttpRequest
;
import
cn.hutool.http.HttpResponse
;
import
com.alibaba.fastjson.JSONObject
;
import
org.junit.Test
;
/**
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0
* @since 1.9.6
*/
public
class
ThirdPartSdkTest
{
@Test
public
void
huawei
()
{
String
code
=
"CF1IE8WDUI7HR0cTOcl59SHBmIo0EGugnY99HTnLjH0BiCu5+maSDDejA7V2FJntFGfdTXY/jD68WZAVW2cMZoXrHW0LHVQ+uYqb498PkdI453sejJcaSIS6bBCZJBNzrYKGk4PYWc5OS/yuPorSSNRlXXhjN9selraIOF+TBMb7wzXDho7FVz/Es2rInRfttnr3AEaIvkg="
;
HttpResponse
response
=
HttpRequest
.
post
(
"https://oauth-login.cloud.huawei.com/oauth2/v2/token"
)
.
form
(
"grant_type"
,
"authorization_code"
)
.
form
(
"code"
,
code
)
.
form
(
"client_id"
,
"100994535"
)
.
form
(
"client_secret"
,
"22aea400bef603fef26d15a79c806eb477b35de0a529758f2a3b1bda32bfb80d"
)
.
form
(
"redirect_uri"
,
"http://localhost:8443/huawei/login"
)
.
execute
();
System
.
out
.
println
(
response
.
body
());
// {"access_token":"CF1IGrYGi\/s0JddMwEQ1i0xBwWI7CepxuAm9HP9wvjuPOYyXItkSh6PVLfeD7AcDD3BS0APzgyyrS\/GK9FF9Hk91WrAROGfTfTVlh0DdEw9k4NW77EjQmA==","expires_in":3600,"refresh_token":"CF41WqZNkgaJhDtW1Kv5rypr8PklmwVsKlAbFLXmxte0mrTdvJd9k8vTrIlw5NoMnNn7nZ2b3fpgsl4zabm10QQEHY2H+s5qwx1dxXR\/arV6JQ9OYMDk+A==","scope":"https:\/\/www.huawei.com\/auth\/account\/mobile.number https:\/\/www.huawei.com\/auth\/account\/base.profile","token_type":"Bearer"}
//
HttpResponse
response2
=
HttpRequest
.
post
(
"https://api.vmall.com/rest.php"
)
.
form
(
"nsp_ts"
,
System
.
currentTimeMillis
())
.
form
(
"access_token"
,
JSONObject
.
parseObject
(
response
.
body
()).
getString
(
"access_token"
))
.
form
(
"nsp_fmt"
,
"JS"
)
// .form("nsp_cb", "")
.
form
(
"nsp_svc"
,
"OpenUP.User.getInfo"
)
.
execute
();
System
.
out
.
println
(
response2
.
body
());
// 华为性别 0是男,女是1
// {"gender":1,"headPictureURL":"https://upfile-drcn.platform.hicloud.com/FileServer/image/b.0260086000226601572.20190415065228.iBKdTsqaNkdPXSz4N7pIRWAgeu45ec3k.1000.9A5467309F9284B267ECA33B59D3D7DA4A71BC732D3BB24EC6B880A73DEE9BAB.jpg","languageCode":"zh-CN","userID":"260086000226601572","userName":"151****2326","userState":1,"userValidStatus":1}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录