Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Yanxianyang
JustAuth
提交
e92f8961
J
JustAuth
项目概览
Yanxianyang
/
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,发现更多精彩内容 >>
未验证
提交
e92f8961
编写于
5月 28, 2019
作者:
智布道
👁
提交者:
GitHub
5月 28, 2019
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #13 from xkcoding/feature-mi
✨
增加小米登录支持
上级
132c6826
a6ed65ce
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
232 addition
and
3 deletion
+232
-3
src/main/java/me/zhyd/oauth/authorization/AuthorizationFactory.java
...ava/me/zhyd/oauth/authorization/AuthorizationFactory.java
+1
-0
src/main/java/me/zhyd/oauth/authorization/MiAuthorization.java
...ain/java/me/zhyd/oauth/authorization/MiAuthorization.java
+19
-0
src/main/java/me/zhyd/oauth/consts/ApiUrl.java
src/main/java/me/zhyd/oauth/consts/ApiUrl.java
+29
-0
src/main/java/me/zhyd/oauth/model/AuthSource.java
src/main/java/me/zhyd/oauth/model/AuthSource.java
+2
-1
src/main/java/me/zhyd/oauth/model/AuthToken.java
src/main/java/me/zhyd/oauth/model/AuthToken.java
+6
-0
src/main/java/me/zhyd/oauth/request/AuthMiRequest.java
src/main/java/me/zhyd/oauth/request/AuthMiRequest.java
+108
-0
src/main/java/me/zhyd/oauth/utils/UrlBuilder.java
src/main/java/me/zhyd/oauth/utils/UrlBuilder.java
+54
-2
src/test/java/me/zhyd/oauth/AuthRequestTest.java
src/test/java/me/zhyd/oauth/AuthRequestTest.java
+13
-0
未找到文件。
src/main/java/me/zhyd/oauth/authorization/AuthorizationFactory.java
浏览文件 @
e92f8961
...
...
@@ -70,6 +70,7 @@ public class AuthorizationFactory {
AuthorizationFactory
.
register
(
AuthSource
.
DOUYIN
,
new
DouyinAuthorization
());
AuthorizationFactory
.
register
(
AuthSource
.
LINKEDIN
,
new
LinkedinAuthorization
());
AuthorizationFactory
.
register
(
AuthSource
.
MICROSOFT
,
new
MicrosoftAuthorization
());
AuthorizationFactory
.
register
(
AuthSource
.
MI
,
new
MiAuthorization
());
loader
=
true
;
}
...
...
src/main/java/me/zhyd/oauth/authorization/MiAuthorization.java
0 → 100644
浏览文件 @
e92f8961
package
me.zhyd.oauth.authorization
;
import
me.zhyd.oauth.config.AuthConfig
;
import
me.zhyd.oauth.utils.UrlBuilder
;
/**
* 小米授权
*
* @author yangkai.shen (https://xkcoding.com)
* @version 1.5
* @since 1.5
*/
public
class
MiAuthorization
implements
Authorization
{
@Override
public
String
getAuthorizeUrl
(
AuthConfig
config
)
{
return
UrlBuilder
.
getMiAuthorizeUrl
(
config
.
getClientId
(),
config
.
getRedirectUri
());
}
}
src/main/java/me/zhyd/oauth/consts/ApiUrl.java
浏览文件 @
e92f8961
...
...
@@ -532,6 +532,35 @@ public enum ApiUrl {
public
String
refresh
()
{
return
"https://login.microsoftonline.com/common/oauth2/v2.0/token"
;
}
},
/**
* 小米
*/
MI
{
@Override
public
String
authorize
()
{
return
"https://account.xiaomi.com/oauth2/authorize"
;
}
@Override
public
String
accessToken
()
{
return
"https://account.xiaomi.com/oauth2/token"
;
}
@Override
public
String
userInfo
()
{
return
"https://open.account.xiaomi.com/user/profile"
;
}
@Override
public
String
revoke
()
{
throw
new
AuthException
(
ResponseStatus
.
UNSUPPORTED
);
}
@Override
public
String
refresh
()
{
return
"https://account.xiaomi.com/oauth2/token"
;
}
};
/**
...
...
src/main/java/me/zhyd/oauth/model/AuthSource.java
浏览文件 @
e92f8961
...
...
@@ -25,5 +25,6 @@ public enum AuthSource {
FACEBOOK
,
DOUYIN
,
LINKEDIN
,
MICROSOFT
MICROSOFT
,
MI
}
src/main/java/me/zhyd/oauth/model/AuthToken.java
浏览文件 @
e92f8961
...
...
@@ -27,4 +27,10 @@ public class AuthToken {
private
String
tokenType
;
private
String
idToken
;
/**
* 小米附带属性
*/
private
String
macAlgorithm
;
private
String
macKey
;
}
src/main/java/me/zhyd/oauth/request/AuthMiRequest.java
0 → 100644
浏览文件 @
e92f8961
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
me.zhyd.oauth.config.AuthConfig
;
import
me.zhyd.oauth.exception.AuthException
;
import
me.zhyd.oauth.model.AuthResponse
;
import
me.zhyd.oauth.model.AuthSource
;
import
me.zhyd.oauth.model.AuthToken
;
import
me.zhyd.oauth.model.AuthUser
;
import
me.zhyd.oauth.utils.UrlBuilder
;
import
java.text.MessageFormat
;
/**
* 小米登录
*
* @author yangkai.shen (https://xkcoding.com)
* @version 1.5
* @since 1.5
*/
public
class
AuthMiRequest
extends
BaseAuthRequest
{
private
static
final
String
PREFIX
=
"&&&START&&&"
;
public
AuthMiRequest
(
AuthConfig
config
)
{
super
(
config
,
AuthSource
.
MI
);
}
@Override
protected
AuthToken
getAccessToken
(
String
code
)
{
String
accessTokenUrl
=
UrlBuilder
.
getMiAccessTokenUrl
(
config
.
getClientId
(),
config
.
getClientSecret
(),
config
.
getRedirectUri
(),
code
);
return
getToken
(
accessTokenUrl
);
}
private
AuthToken
getToken
(
String
accessTokenUrl
)
{
HttpResponse
response
=
HttpRequest
.
get
(
accessTokenUrl
).
execute
();
String
jsonStr
=
StrUtil
.
replace
(
response
.
body
(),
PREFIX
,
StrUtil
.
EMPTY
);
JSONObject
object
=
JSONObject
.
parseObject
(
jsonStr
);
if
(
object
.
containsKey
(
"error"
))
{
throw
new
AuthException
(
object
.
getString
(
"error_description"
));
}
return
AuthToken
.
builder
()
.
accessToken
(
object
.
getString
(
"access_token"
))
.
expireIn
(
object
.
getIntValue
(
"expires_in"
))
.
scope
(
object
.
getString
(
"scope"
))
.
tokenType
(
object
.
getString
(
"token_type"
))
.
refreshToken
(
object
.
getString
(
"refresh_token"
))
.
openId
(
object
.
getString
(
"openId"
))
.
macAlgorithm
(
object
.
getString
(
"mac_algorithm"
))
.
macKey
(
object
.
getString
(
"mac_key"
))
.
build
();
}
@Override
protected
AuthUser
getUserInfo
(
AuthToken
authToken
)
{
// 获取用户信息
HttpResponse
userResponse
=
HttpRequest
.
get
(
UrlBuilder
.
getMiUserInfoUrl
(
config
.
getClientId
(),
authToken
.
getAccessToken
()))
.
execute
();
JSONObject
userProfile
=
JSONObject
.
parseObject
(
userResponse
.
body
());
if
(
StrUtil
.
equalsIgnoreCase
(
userProfile
.
getString
(
"result"
),
"error"
))
{
throw
new
AuthException
(
userProfile
.
getString
(
"description"
));
}
JSONObject
user
=
userProfile
.
getJSONObject
(
"data"
);
AuthUser
authUser
=
AuthUser
.
builder
()
.
uuid
(
authToken
.
getOpenId
())
.
username
(
user
.
getString
(
"miliaoNick"
))
.
nickname
(
user
.
getString
(
"miliaoNick"
))
.
avatar
(
user
.
getString
(
"miliaoIcon"
))
.
email
(
user
.
getString
(
"mail"
))
.
token
(
authToken
)
.
source
(
AuthSource
.
MI
)
.
build
();
// 获取用户邮箱手机号等信息
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
());
if
(!
StrUtil
.
equalsIgnoreCase
(
userEmailPhone
.
getString
(
"result"
),
"error"
))
{
JSONObject
emailPhone
=
userEmailPhone
.
getJSONObject
(
"data"
);
authUser
.
setEmail
(
emailPhone
.
getString
(
"email"
));
}
return
authUser
;
}
/**
* 刷新access token (续期)
*
* @param authToken 登录成功后返回的Token信息
* @return AuthResponse
*/
@Override
public
AuthResponse
refresh
(
AuthToken
authToken
)
{
String
miRefreshUrl
=
UrlBuilder
.
getMiRefreshUrl
(
config
.
getClientId
(),
config
.
getClientSecret
(),
config
.
getRedirectUri
(),
authToken
.
getRefreshToken
());
return
AuthResponse
.
builder
().
code
(
ResponseStatus
.
SUCCESS
.
getCode
()).
data
(
getToken
(
miRefreshUrl
)).
build
();
}
}
src/main/java/me/zhyd/oauth/utils/UrlBuilder.java
浏览文件 @
e92f8961
...
...
@@ -671,7 +671,6 @@ public class UrlBuilder {
return
MessageFormat
.
format
(
LINKEDIN_REFRESH_TOKEN_PATTERN
,
ApiUrl
.
LINKEDIN
.
refresh
(),
clientId
,
clientSecret
,
refreshToken
);
}
private
static
final
String
MICROSOFT_AUTHORIZE_PATTERN
=
"{0}?client_id={1}&response_type=code&redirect_uri={2}&response_mode=query&scope=offline_access%20user.read%20mail.read&state={3}"
;
private
static
final
String
MICROSOFT_ACCESS_TOKEN_PATTERN
=
"{0}?client_id={1}&client_secret={2}&scope=user.read%20mail.read&redirect_uri={3}&code={4}&grant_type=authorization_code"
;
private
static
final
String
MICROSOFT_USER_INFO_PATTERN
=
"{0}"
;
...
...
@@ -698,7 +697,7 @@ public class UrlBuilder {
* @param code 微软 授权前的code,用来换token
* @return full url
*/
public
static
String
getMicrosoftAccessTokenUrl
(
String
clientId
,
String
clientSecret
,
String
redirectUrl
,
String
code
)
{
public
static
String
getMicrosoftAccessTokenUrl
(
String
clientId
,
String
clientSecret
,
String
redirectUrl
,
String
code
)
{
return
MessageFormat
.
format
(
MICROSOFT_ACCESS_TOKEN_PATTERN
,
ApiUrl
.
MICROSOFT
.
accessToken
(),
clientId
,
clientSecret
,
redirectUrl
,
code
);
}
...
...
@@ -723,4 +722,57 @@ public class UrlBuilder {
public
static
String
getMicrosoftRefreshUrl
(
String
clientId
,
String
clientSecret
,
String
redirectUrl
,
String
refreshToken
)
{
return
MessageFormat
.
format
(
MICROSOFT_REFRESH_TOKEN_PATTERN
,
ApiUrl
.
MICROSOFT
.
refresh
(),
clientId
,
clientSecret
,
redirectUrl
,
refreshToken
);
}
private
static
final
String
MI_AUTHORIZE_PATTERN
=
"{0}?client_id={1}&redirect_uri={2}&response_type=code&scope=user/profile%20user/openIdV2%20user/phoneAndEmail&state={3}&skip_confirm=false"
;
private
static
final
String
MI_ACCESS_TOKEN_PATTERN
=
"{0}?client_id={1}&client_secret={2}&redirect_uri={3}&code={4}&grant_type=authorization_code"
;
private
static
final
String
MI_USER_INFO_PATTERN
=
"{0}?clientId={1}&token={2}"
;
private
static
final
String
MI_REFRESH_TOKEN_PATTERN
=
"{0}?client_id={1}&client_secret={2}&redirect_uri={3}&refresh_token={4}&grant_type=refresh_token"
;
/**
* 获取小米授权地址
*
* @param clientId 小米 应用的Client ID
* @param redirectUrl 小米 应用授权成功后的回调地址
* @return full url
*/
public
static
String
getMiAuthorizeUrl
(
String
clientId
,
String
redirectUrl
)
{
return
MessageFormat
.
format
(
MI_AUTHORIZE_PATTERN
,
ApiUrl
.
MI
.
authorize
(),
clientId
,
redirectUrl
,
System
.
currentTimeMillis
());
}
/**
* 获取小米 token的接口地址
*
* @param clientId 小米 应用的Client ID
* @param clientSecret 小米 应用的Client Secret
* @param redirectUrl 小米 应用授权成功后的回调地址
* @param code 小米 授权前的code,用来换token
* @return full url
*/
public
static
String
getMiAccessTokenUrl
(
String
clientId
,
String
clientSecret
,
String
redirectUrl
,
String
code
)
{
return
MessageFormat
.
format
(
MI_ACCESS_TOKEN_PATTERN
,
ApiUrl
.
MI
.
accessToken
(),
clientId
,
clientSecret
,
redirectUrl
,
code
);
}
/**
* 获取小米用户详情的接口地址
*
* @param clientId 小米 应用的client_key
* @param token token
* @return full url
*/
public
static
String
getMiUserInfoUrl
(
String
clientId
,
String
token
)
{
return
MessageFormat
.
format
(
MI_USER_INFO_PATTERN
,
ApiUrl
.
MI
.
userInfo
(),
clientId
,
token
);
}
/**
* 获取小米 刷新令牌 地址
*
* @param clientId 小米 应用的client_key
* @param clientSecret 小米 应用的Client Secret
* @param redirectUrl 小米 应用授权成功后的回调地址
* @param refreshToken 小米 应用返回的refresh_token
* @return full url
*/
public
static
String
getMiRefreshUrl
(
String
clientId
,
String
clientSecret
,
String
redirectUrl
,
String
refreshToken
)
{
return
MessageFormat
.
format
(
MI_REFRESH_TOKEN_PATTERN
,
ApiUrl
.
MI
.
refresh
(),
clientId
,
clientSecret
,
redirectUrl
,
refreshToken
);
}
}
src/test/java/me/zhyd/oauth/AuthRequestTest.java
浏览文件 @
e92f8961
...
...
@@ -180,4 +180,17 @@ public class AuthRequestTest {
// 授权登录后会返回一个code,用这个code进行登录
AuthResponse
login
=
authRequest
.
login
(
"code"
);
}
@Test
public
void
miTest
()
{
AuthRequest
authRequest
=
new
AuthMiRequest
(
AuthConfig
.
builder
()
.
clientId
(
"clientId"
)
.
clientSecret
(
"clientSecret"
)
.
redirectUri
(
"redirectUri"
)
.
build
());
// 返回授权页面,可自行调整
String
url
=
authRequest
.
authorize
();
// 授权登录后会返回一个code,用这个code进行登录
AuthResponse
login
=
authRequest
.
login
(
"code"
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录