#238 飞书扫码登录失败

This commit is contained in:
MaxKey 2024-11-25 07:38:47 +08:00
parent 3ee742d8eb
commit 7efa9dd9f5
12 changed files with 127 additions and 146 deletions

View File

@ -119,7 +119,7 @@ public class AuthJwtService {
* @return true or false * @return true or false
*/ */
public boolean validateJwtToken(String authToken) { public boolean validateJwtToken(String authToken) {
if(StringUtils.isNotBlank(authToken)) { if(StringUtils.isNotBlank(authToken) && authToken.length() > 20) {
try { try {
JWTClaimsSet claims = resolve(authToken); JWTClaimsSet claims = resolve(authToken);
boolean isExpiration = claims.getExpirationTime().after(DateTime.now().toDate()); boolean isExpiration = claims.getExpirationTime().after(DateTime.now().toDate());

View File

@ -64,7 +64,7 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
SignPrincipal principal = AuthorizationUtils.getPrincipal(); SignPrincipal principal = AuthorizationUtils.getPrincipal();
//判断用户是否登录,判断用户是否登录用户 //判断用户是否登录,判断用户是否登录用户
if(principal == null){ if(principal == null){
_logger.trace("No Authentication ... forward to /auth/entrypoint , request URI " + request.getRequestURI()); _logger.debug("No Authentication ... forward to /auth/entrypoint , request URI {}" , request.getRequestURI());
RequestDispatcher dispatcher = request.getRequestDispatcher("/auth/entrypoint"); RequestDispatcher dispatcher = request.getRequestDispatcher("/auth/entrypoint");
dispatcher.forward(request, response); dispatcher.forward(request, response);
return false; return false;

View File

@ -107,11 +107,11 @@ public class AbstractSocialSignOnEndpoint {
} }
AuthResponse<?> authResponse=authRequest.login(authCallback); AuthResponse<?> authResponse=authRequest.login(authCallback);
_logger.debug("Response : " + authResponse.getData()); _logger.debug("Response : {}" , authResponse.getData());
String socialUserId = socialSignOnProviderService.getAccountId(provider, authResponse);
socialsAssociate =new SocialsAssociate(); socialsAssociate =new SocialsAssociate();
socialsAssociate.setProvider(provider); socialsAssociate.setProvider(provider);
socialsAssociate.setSocialUserId( socialsAssociate.setSocialUserId(socialUserId);
socialSignOnProviderService.getAccountId(provider, authResponse));
socialsAssociate.setInstId(instId); socialsAssociate.setInstId(instId);
return socialsAssociate; return socialsAssociate;

View File

@ -35,7 +35,6 @@ import org.dromara.maxkey.web.WebContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@ -47,17 +46,14 @@ import java.util.Map;
* @author Crystal.Sea * @author Crystal.Sea
* *
*/ */
@Controller @RestController
@RequestMapping(value = "/logon/oauth20") @RequestMapping(value = "/logon/oauth20")
public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
static final Logger _logger = LoggerFactory.getLogger(SocialSignOnEndpoint.class); static final Logger _logger = LoggerFactory.getLogger(SocialSignOnEndpoint.class);
@RequestMapping(value={"/authorize/{provider}"}, method = RequestMethod.GET) @GetMapping("/authorize/{provider}")
@ResponseBody public Message<Object> authorize( HttpServletRequest request,@PathVariable("provider") String provider) {
public Message<Object> authorize( HttpServletRequest request, _logger.trace("SocialSignOn provider : {}" , provider);
@PathVariable("provider") String provider
) {
_logger.trace("SocialSignOn provider : " + provider);
String instId = WebContext.getInst().getId(); String instId = WebContext.getInst().getId();
String originURL =WebContext.getContextPath(request,false); String originURL =WebContext.getContextPath(request,false);
String authorizationUrl = String authorizationUrl =
@ -67,14 +63,12 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
originURL + applicationConfig.getFrontendUri() originURL + applicationConfig.getFrontendUri()
).authorize(authTokenService.genRandomJwt()); ).authorize(authTokenService.genRandomJwt());
_logger.trace("authorize SocialSignOn : " + authorizationUrl); _logger.trace("authorize SocialSignOn : {}" , authorizationUrl);
return new Message<Object>((Object)authorizationUrl); return new Message<Object>(authorizationUrl);
} }
@RequestMapping(value={"/scanqrcode/{provider}"}, method = RequestMethod.GET) @GetMapping("/scanqrcode/{provider}")
@ResponseBody public Message<SocialsProvider> scanQRCode(HttpServletRequest request,@PathVariable("provider") String provider) {
public Message<SocialsProvider> scanQRCode(HttpServletRequest request,
@PathVariable("provider") String provider) {
String instId = WebContext.getInst().getId(); String instId = WebContext.getInst().getId();
String originURL =WebContext.getContextPath(request,false); String originURL =WebContext.getContextPath(request,false);
AuthRequest authRequest = AuthRequest authRequest =
@ -82,30 +76,30 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
instId, instId,
provider, provider,
originURL + applicationConfig.getFrontendUri()); originURL + applicationConfig.getFrontendUri());
SocialsProvider scanQrProvider = null;
if(authRequest != null ) {
String state = UUID.generate().toString();
//String state = authTokenService.genRandomJwt();
authRequest.authorize(state);
if(authRequest == null ) { SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider);
_logger.error("build authRequest fail ."); scanQrProvider = new SocialsProvider(socialSignOnProvider);
scanQrProvider.setState(state);
scanQrProvider.setRedirectUri(
socialSignOnProviderService.getRedirectUri(
originURL + applicationConfig.getFrontendUri(), provider));
//缓存state票据在缓存或者是redis中五分钟过期
if (provider.equalsIgnoreCase(AuthMaxkeyRequest.KEY)) {
socialSignOnProviderService.setToken(state);
}
}else {
_logger.error("build authRequest fail .");
} }
String state = UUID.generate().toString();
//String state = authTokenService.genRandomJwt();
authRequest.authorize(state);
SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider); return new Message<>(scanQrProvider);
SocialsProvider scanQrProvider = new SocialsProvider(socialSignOnProvider);
scanQrProvider.setState(state);
scanQrProvider.setRedirectUri(
socialSignOnProviderService.getRedirectUri(
originURL + applicationConfig.getFrontendUri(), provider));
//缓存state票据在缓存或者是redis中五分钟过期
if (provider.equalsIgnoreCase(AuthMaxkeyRequest.KEY)) {
socialSignOnProviderService.setToken(state);
}
return new Message<SocialsProvider>(scanQrProvider);
} }
@GetMapping("/bind/{provider}")
@RequestMapping(value={"/bind/{provider}"}, method = RequestMethod.GET)
public Message<AuthJwt> bind(@PathVariable("provider") String provider, public Message<AuthJwt> bind(@PathVariable("provider") String provider,
@CurrentUser UserInfo userInfo, @CurrentUser UserInfo userInfo,
HttpServletRequest request) { HttpServletRequest request) {
@ -118,24 +112,18 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
socialsAssociate.setUserId(userInfo.getId()); socialsAssociate.setUserId(userInfo.getId());
socialsAssociate.setUsername(userInfo.getUsername()); socialsAssociate.setUsername(userInfo.getUsername());
socialsAssociate.setInstId(userInfo.getInstId()); socialsAssociate.setInstId(userInfo.getInstId());
//socialsAssociate.setAccessToken(JsonUtils.object2Json(accessToken)); _logger.debug("Social Bind : {}",socialsAssociate);
//socialsAssociate.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject()));
_logger.debug("Social Bind : "+socialsAssociate);
this.socialsAssociateService.delete(socialsAssociate); this.socialsAssociateService.delete(socialsAssociate);
this.socialsAssociateService.insert(socialsAssociate); this.socialsAssociateService.insert(socialsAssociate);
return new Message<AuthJwt>(); return new Message<>();
}catch(Exception e) { }catch(Exception e) {
_logger.error("callback Exception ",e); _logger.error("callback Exception ",e);
} }
return new Message<>(Message.ERROR);
return new Message<AuthJwt>(Message.ERROR);
} }
@GetMapping("/callback/{provider}")
public Message<AuthJwt> callback(@PathVariable("provider") String provider,HttpServletRequest request) {
@RequestMapping(value={"/callback/{provider}"}, method = RequestMethod.GET)
public Message<AuthJwt> callback(@PathVariable("provider") String provider,
HttpServletRequest request) {
//auth call back may exception //auth call back may exception
try { try {
String originURL =WebContext.getContextPath(request,false); String originURL =WebContext.getContextPath(request,false);
@ -145,36 +133,38 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
SocialsAssociate socialssssociate1 = this.socialsAssociateService.get(socialsAssociate); SocialsAssociate socialssssociate1 = this.socialsAssociateService.get(socialsAssociate);
_logger.debug("Loaded SocialSignOn Socials Associate : "+socialssssociate1); _logger.debug("Loaded SocialSignOn Socials Associate : {}",socialssssociate1);
if (null == socialssssociate1) { if (null == socialssssociate1) {
//如果存在第三方ID并且在数据库无法找到映射关系则进行绑定逻辑 //如果存在第三方ID并且在数据库无法找到映射关系则进行绑定逻辑
if (StringUtils.isNotEmpty(socialsAssociate.getSocialUserId())) { if (StringUtils.isNotEmpty(socialsAssociate.getSocialUserId())) {
//返回message为第三方用户标识 //返回message为第三方用户标识
return new Message<AuthJwt>(Message.PROMPT,socialsAssociate.getSocialUserId()); return new Message<>(Message.PROMPT,socialsAssociate.getSocialUserId());
} }
} }
socialsAssociate = socialssssociate1; socialsAssociate = socialssssociate1;
_logger.debug("Social Sign On from {} mapping to user {}", if(socialsAssociate != null) {
_logger.debug("Social Sign On from {} mapping to user {}",
socialsAssociate.getProvider(),socialsAssociate.getUsername()); socialsAssociate.getProvider(),socialsAssociate.getUsername());
LoginCredential loginCredential =new LoginCredential(
socialsAssociate.getUsername(),"",ConstsLoginType.SOCIALSIGNON);
SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider);
loginCredential.setProvider(socialSignOnProvider.getProviderName());
LoginCredential loginCredential =new LoginCredential( Authentication authentication = authenticationProvider.authenticate(loginCredential,true);
socialsAssociate.getUsername(),"",ConstsLoginType.SOCIALSIGNON); socialsAssociate.setSocialUserInfo(accountJsonString);
SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider);
loginCredential.setProvider(socialSignOnProvider.getProviderName());
Authentication authentication = authenticationProvider.authenticate(loginCredential,true); this.socialsAssociateService.update(socialsAssociate);
//socialsAssociate.setAccessToken(JsonUtils.object2Json(this.accessToken)); return new Message<>(authTokenService.genAuthJwt(authentication));
socialsAssociate.setSocialUserInfo(accountJsonString); }else {
//socialsAssociate.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject()));
this.socialsAssociateService.update(socialsAssociate); }
return new Message<AuthJwt>(authTokenService.genAuthJwt(authentication));
}catch(Exception e) { }catch(Exception e) {
_logger.error("callback Exception ",e); _logger.error("callback Exception ",e);
return new Message<AuthJwt>(Message.ERROR);
} }
return new Message<>(Message.ERROR);
} }
@ -182,14 +172,14 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
* 提供给第三方应用关联用户接口 * 提供给第三方应用关联用户接口
* @return * @return
*/ */
@RequestMapping(value={"/workweixin/qr/auth/login"}, method = {RequestMethod.POST}) @PostMapping("/workweixin/qr/auth/login")
public Message<AuthJwt> qrAuthLogin( public Message<AuthJwt> qrAuthLogin(
@RequestParam Map<String, String> param, @RequestParam Map<String, String> param,
HttpServletRequest request) { HttpServletRequest request) {
try { try {
if (null == param){ if (null == param){
return new Message<AuthJwt>(Message.ERROR); return new Message<>(Message.ERROR);
} }
String token = param.get("token"); String token = param.get("token");
String username = param.get("username"); String username = param.get("username");
@ -199,15 +189,15 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
//设置token和用户绑定 //设置token和用户绑定
boolean flag = this.socialSignOnProviderService.bindtoken(token,username); boolean flag = this.socialSignOnProviderService.bindtoken(token,username);
if (flag) { if (flag) {
return new Message<AuthJwt>(); return new Message<>();
} }
} else { } else {
return new Message<AuthJwt>(Message.WARNING,"Invalid token"); return new Message<>(Message.WARNING,"Invalid token");
} }
}catch(Exception e) { }catch(Exception e) {
_logger.error("qrAuthLogin Exception ",e); _logger.error("qrAuthLogin Exception ",e);
} }
return new Message<AuthJwt>(Message.ERROR); return new Message<>(Message.ERROR);
} }
@ -218,23 +208,23 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
* @param request * @param request
* @return * @return
*/ */
@RequestMapping(value={"/qrcallback/{provider}/{state}"}, method = RequestMethod.GET) @PostMapping("/qrcallback/{provider}/{state}")
public Message<AuthJwt> qrcallback(@PathVariable("provider") String provider,@PathVariable("state") String state, public Message<AuthJwt> qrcallback(@PathVariable("provider") String provider,@PathVariable("state") String state,
HttpServletRequest request) { HttpServletRequest request) {
try { try {
//判断只有maxkey扫码 //判断只有maxkey扫码
if (!provider.equalsIgnoreCase(AuthMaxkeyRequest.KEY)) { if (!provider.equalsIgnoreCase(AuthMaxkeyRequest.KEY)) {
return new Message<AuthJwt>(Message.ERROR); return new Message<>(Message.ERROR);
} }
String loginName = socialSignOnProviderService.getToken(state); String loginName = socialSignOnProviderService.getToken(state);
if (StringUtils.isEmpty(loginName)) { if (StringUtils.isEmpty(loginName)) {
//二维码过期 //二维码过期
return new Message<AuthJwt>(Message.PROMPT); return new Message<>(Message.PROMPT);
} }
if("-1".equalsIgnoreCase(loginName)){ if("-1".equalsIgnoreCase(loginName)){
//暂无用户扫码 //暂无用户扫码
return new Message<AuthJwt>(Message.WARNING); return new Message<>(Message.WARNING);
} }
String instId = WebContext.getInst().getId(); String instId = WebContext.getInst().getId();
@ -246,29 +236,25 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
socialsAssociate = this.socialsAssociateService.get(socialsAssociate); socialsAssociate = this.socialsAssociateService.get(socialsAssociate);
_logger.debug("qrcallback Loaded SocialSignOn Socials Associate : "+socialsAssociate); _logger.debug("qrcallback Loaded SocialSignOn Socials Associate : {}",socialsAssociate);
if(null == socialsAssociate) { if(null == socialsAssociate) {
return new Message<AuthJwt>(Message.ERROR); return new Message<>(Message.ERROR);
} }
_logger.debug("qrcallback Social Sign On from {} mapping to user {}", socialsAssociate.getProvider(),socialsAssociate.getUsername());
LoginCredential loginCredential =new LoginCredential( LoginCredential loginCredential =new LoginCredential(
socialsAssociate.getUsername(),"",ConstsLoginType.SOCIALSIGNON); socialsAssociate.getUsername(),"",ConstsLoginType.SOCIALSIGNON);
SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider); SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider);
loginCredential.setProvider(socialSignOnProvider.getProviderName()); loginCredential.setProvider(socialSignOnProvider.getProviderName());
Authentication authentication = authenticationProvider.authenticate(loginCredential,true); Authentication authentication = authenticationProvider.authenticate(loginCredential,true);
//socialsAssociate.setAccessToken(JsonUtils.object2Json(this.accessToken));
socialsAssociate.setSocialUserInfo(accountJsonString); socialsAssociate.setSocialUserInfo(accountJsonString);
//socialsAssociate.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject()));
this.socialsAssociateService.update(socialsAssociate); this.socialsAssociateService.update(socialsAssociate);
return new Message<AuthJwt>(authTokenService.genAuthJwt(authentication)); return new Message<>(authTokenService.genAuthJwt(authentication));
}catch(Exception e) { }catch(Exception e) {
_logger.error("qrcallback Exception ",e); _logger.error("qrcallback Exception ",e);
return new Message<AuthJwt>(Message.ERROR); return new Message<>(Message.ERROR);
} }
} }
} }

View File

@ -43,7 +43,7 @@ import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.*; import me.zhyd.oauth.request.*;
public class SocialSignOnProviderService{ public class SocialSignOnProviderService{
private static Logger _logger = LoggerFactory.getLogger(SocialSignOnProviderService.class); private static final Logger _logger = LoggerFactory.getLogger(SocialSignOnProviderService.class);
private static final String DEFAULT_SELECT_STATEMENT = "select * from mxk_socials_provider where instid = ? and status = 1 order by sortindex"; private static final String DEFAULT_SELECT_STATEMENT = "select * from mxk_socials_provider where instid = ? and status = 1 order by sortindex";
@ -52,7 +52,7 @@ public class SocialSignOnProviderService{
.expireAfterWrite(ConstsTimeInterval.ONE_HOUR, TimeUnit.MINUTES) .expireAfterWrite(ConstsTimeInterval.ONE_HOUR, TimeUnit.MINUTES)
.build(); .build();
HashMap<String ,SocialsProvider>socialSignOnProviderMaps = new HashMap<String ,SocialsProvider>(); HashMap<String ,SocialsProvider>socialSignOnProviderMaps = new HashMap<>();
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
@ -199,9 +199,9 @@ public class SocialSignOnProviderService{
List<SocialsProvider> listSocialsProvider = jdbcTemplate.query( List<SocialsProvider> listSocialsProvider = jdbcTemplate.query(
DEFAULT_SELECT_STATEMENT, DEFAULT_SELECT_STATEMENT,
new SocialsProviderRowMapper(),instId); new SocialsProviderRowMapper(),instId);
_logger.trace("query SocialsProvider " + listSocialsProvider); _logger.trace("query SocialsProvider {}" , listSocialsProvider);
List<SocialsProvider> socialSignOnProviders = new ArrayList<SocialsProvider>(); List<SocialsProvider> socialSignOnProviders = new ArrayList<>();
socialsLogin = new SocialsProviderLogin(socialSignOnProviders); socialsLogin = new SocialsProviderLogin(socialSignOnProviders);
for(SocialsProvider socialsProvider : listSocialsProvider){ for(SocialsProvider socialsProvider : listSocialsProvider){
_logger.debug("Social Provider {} ({})" , _logger.debug("Social Provider {} ({})" ,

View File

@ -107,14 +107,14 @@ export class DefaultInterceptor implements HttpInterceptor {
*/ */
private refreshTokenRequest(): Observable<any> { private refreshTokenRequest(): Observable<any> {
const model = this.tokenSrv.get(); const model = this.tokenSrv.get();
return this.http.post(`/auth/token/refresh`, null, { refresh_token: model?.['refresh_token'] || '' }); return this.http.post(`/auth/token/refresh?_allow_anonymous=true`, null, { refresh_token: model?.['refresh_token'] || '' });
} }
// #region 刷新Token方式一使用 401 重新刷新 Token // #region 刷新Token方式一使用 401 重新刷新 Token
private tryRefreshToken(ev: HttpResponseBase, req: HttpRequest<any>, next: HttpHandler): Observable<any> { private tryRefreshToken(ev: HttpResponseBase, req: HttpRequest<any>, next: HttpHandler): Observable<any> {
// 1、若请求为刷新Token请求表示来自刷新Token可以直接跳转登录页 // 1、若请求为刷新Token请求表示来自刷新Token可以直接跳转登录页
if ([`/auth/token/refresh`].some(url => req.url.includes(url))) { if ([`/auth/token/refresh?_allow_anonymous=true`].some(url => req.url.includes(url))) {
this.toLogin(); this.toLogin();
return throwError(ev); return throwError(ev);
} }

View File

@ -19,9 +19,10 @@ import { ActivatedRoute, Router } from '@angular/router';
import { ReuseTabService } from '@delon/abc/reuse-tab'; import { ReuseTabService } from '@delon/abc/reuse-tab';
import { SettingsService } from '@delon/theme'; import { SettingsService } from '@delon/theme';
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal'; import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
import { AuthnService } from '../../service/authn.service'; import { AuthnService } from '../../service/authn.service';
import { SocialsProviderService } from '../../service/socials-provider.service'; import { SocialsProviderService } from '../../service/socials-provider.service';
import {SocialsProviderBindUserComponent} from "./socials-provider-bind-user/socials-provider-bind-user.component"; import { SocialsProviderBindUserComponent } from './socials-provider-bind-user/socials-provider-bind-user.component';
@Component({ @Component({
selector: 'app-callback', selector: 'app-callback',
@ -52,10 +53,9 @@ export class CallbackComponent implements OnInit {
this.reuseTabService.clear(); this.reuseTabService.clear();
// 设置用户Token信息 // 设置用户Token信息
this.authnService.auth(res.data); this.authnService.auth(res.data);
} } else if (res.code === 102) {
else if (res.code === 102) {
//绑定用户 //绑定用户
this.openBindUser(res.message) this.openBindUser(res.message);
return; return;
} }
this.authnService.navigate({}); this.authnService.navigate({});
@ -70,7 +70,7 @@ export class CallbackComponent implements OnInit {
} }
openBindUser(socialUserId: String) { openBindUser(socialUserId: String) {
console.log("bind user : ",this.provider,socialUserId); console.log('bind user : ', this.provider, socialUserId);
const modal = this.modalService.create({ const modal = this.modalService.create({
nzContent: SocialsProviderBindUserComponent, nzContent: SocialsProviderBindUserComponent,
nzViewContainerRef: this.viewContainerRef, nzViewContainerRef: this.viewContainerRef,
@ -83,10 +83,7 @@ export class CallbackComponent implements OnInit {
// Return a result when closed // Return a result when closed
modal.afterClose.subscribe(result => { modal.afterClose.subscribe(result => {
if (result.refresh) { if (result.refresh) {
} }
}); });
} }
} }

View File

@ -14,7 +14,7 @@
<i nz-icon nzType="mobile" nzTheme="outline"></i> <i nz-icon nzType="mobile" nzTheme="outline"></i>
{{ 'mxk.login.tab-mobile' | i18n }} {{ 'mxk.login.tab-mobile' | i18n }}
</label> </label>
<label nz-radio-button nzValue="qrscan" style="width: 50%; text-align: center" (click)="getLoginQrCode()"> <label nz-radio-button nzValue="qrscan" style="width: 50%; text-align: center" (click)="getScanQrCode()">
<i nz-icon nzType="qrcode" nzTheme="outline"></i>{{ 'mxk.login.tab-qrscan' | i18n }} <i nz-icon nzType="qrcode" nzTheme="outline"></i>{{ 'mxk.login.tab-qrscan' | i18n }}
</label> </label>
</nz-radio-group> </nz-radio-group>
@ -82,10 +82,10 @@
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
<div nz-row *ngIf="loginType=='qrscan'"> <div nz-row *ngIf="loginType == 'qrscan'">
<div class="qrcode" id="div_qrcodelogin" style="background: #fff;padding: 20px;"></div> <div class="qrcode" id="div_qrcodelogin" style="background: #fff; padding: 20px"></div>
<div id="qrexpire" *ngIf="qrexpire" style="width: 100%;text-align: center;background: #fff;padding-bottom: 20px;"> <div id="qrexpire" *ngIf="qrexpire" style="width: 100%; text-align: center; background: #fff; padding-bottom: 20px">
二维码过期 <a href="javascript:void(0);" (click)="getLoginQrCode()">刷新</a> 二维码过期 <a href="javascript:void(0);" (click)="getScanQrCode()">刷新</a>
</div> </div>
</div> </div>
<nz-form-item *ngIf="loginType == 'normal' || loginType == 'mobile'"> <nz-form-item *ngIf="loginType == 'normal' || loginType == 'mobile'">

View File

@ -45,9 +45,9 @@ export class UserLoginComponent implements OnInit, OnDestroy {
providers: NzSafeAny[]; providers: NzSafeAny[];
qrScan: string; qrScan: string;
} = { } = {
providers: [], providers: [],
qrScan: '' qrScan: ''
}; };
form: FormGroup; form: FormGroup;
error = ''; error = '';
@ -309,32 +309,50 @@ export class UserLoginComponent implements OnInit, OnDestroy {
/** /**
* *
*/ */
getLoginQrCode() { getScanQrCode() {
this.qrexpire = false; this.authnService.clearUser();
console.log(`qrScan : ${this.socials.qrScan}`);
this.qrCodeService.getLoginQrCode().subscribe(res => { if (this.socials.qrScan === 'workweixin' || this.socials.qrScan === 'dingtalk' || this.socials.qrScan === 'feishu') {
if (res.code === 0 && res.data.rqCode) { this.socialsProviderService.scanqrcode(this.socials.qrScan).subscribe(res => {
// 使用返回的 rqCode if (res.code === 0) {
const qrImageElement = document.getElementById('div_qrcodelogin'); if (this.socials.qrScan === 'workweixin') {
this.ticket = res.data.ticket; this.qrScanWorkweixin(res.data);
if (qrImageElement) { } else if (this.socials.qrScan === 'dingtalk') {
qrImageElement.innerHTML = `<img src="${res.data.rqCode}" alt="QR Code" style="width: 200px; height: 200px;">`; this.qrScanDingtalk(res.data);
} else if (this.socials.qrScan === 'feishu') {
this.qrScanFeishu(res.data);
}
} }
});
} else {
this.qrexpire = false;
if (this.interval$) {
clearInterval(this.interval$);
}
this.qrCodeService.getLoginQrCode().subscribe(res => {
if (res.code === 0 && res.data.rqCode) {
// 使用返回的 rqCode
const qrImageElement = document.getElementById('div_qrcodelogin');
this.ticket = res.data.ticket;
if (qrImageElement) {
qrImageElement.innerHTML = `<img src="${res.data.rqCode}" alt="QR Code" style="width: 200px; height: 200px;">`;
}
/* // 5 qrexpire false /* // 5 qrexpire false
setTimeout(() => { setTimeout(() => {
this.qrexpire = true; this.qrexpire = true;
this.cdr.detectChanges(); // 更新视图 this.cdr.detectChanges(); // 更新视图
}, 5 * 60 * 1000); // 5 分钟*/ }, 5 * 60 * 1000); // 5 分钟*/
this.loginByQrCode(); this.scanQrCodeLogin();
} }
}); });
}
} }
/** /**
* *
*/ */
loginByQrCode() { scanQrCodeLogin() {
const interval = setInterval(() => { const interval = setInterval(() => {
this.qrCodeService this.qrCodeService
.loginByQrCode({ .loginByQrCode({
@ -369,27 +387,6 @@ export class UserLoginComponent implements OnInit, OnDestroy {
}, 5 * 1000); // 5 seconds }, 5 * 1000); // 5 seconds
} }
getQrCode(): void {
this.qrexpire = false;
if (this.interval$) {
clearInterval(this.interval$);
}
this.authnService.clearUser();
this.socialsProviderService.scanqrcode(this.socials.qrScan).subscribe(res => {
if (res.code === 0) {
if (this.socials.qrScan === 'workweixin') {
this.qrScanWorkweixin(res.data);
} else if (this.socials.qrScan === 'dingtalk') {
this.qrScanDingtalk(res.data);
} else if (this.socials.qrScan === 'maxkey') {
this.qrScanMaxkey(res.data);
} else if (this.socials.qrScan === 'feishu') {
this.qrScanFeishu(res.data);
}
}
});
}
// #endregion // #endregion
ngOnDestroy(): void { ngOnDestroy(): void {

View File

@ -51,7 +51,7 @@ export class SocialsProviderService extends BaseService<SocialsProvider> {
return this.getByParams(params, `/logon/oauth20/bind/${provider}?_allow_anonymous=true`); return this.getByParams(params, `/logon/oauth20/bind/${provider}?_allow_anonymous=true`);
} }
qrcallback(provider: string, token: string ): Observable<Message<SocialsProvider>> { qrcallback(provider: string, token: string): Observable<Message<SocialsProvider>> {
return this.getByParams({}, `/logon/oauth20/qrcallback/${provider}/${token}?_allow_anonymous=true`); return this.getByParams({}, `/logon/oauth20/qrcallback/${provider}/${token}?_allow_anonymous=true`);
} }
} }

View File

@ -168,8 +168,9 @@
</script> </script>
<!--飞书--> <!--飞书-->
<!--
<script src="http://sf3-cn.feishucdn.com/obj/static/lark/passport/qrcode/LarkSSOSDKWebQRCode-1.0.1.js"></script> <script src="http://lf-package-cn.feishucdn.com/obj/feishu-static/lark/passport/qrcode/LarkSSOSDKWebQRCode-1.0.3.js"></script>
<script type="text/javascript"> <script type="text/javascript">
var fsredirectUri = ""; var fsredirectUri = "";
var QRLoginObj; var QRLoginObj;
@ -190,6 +191,5 @@
window.attachEvent('onmessage', handleMessage); window.attachEvent('onmessage', handleMessage);
} }
</script> </script>
-->
</html> </html>

View File

@ -107,6 +107,7 @@ public class MaxKeyMvcConfig implements WebMvcConfigurer {
.addPathPatterns("/logout") .addPathPatterns("/logout")
.addPathPatterns("/logout/**") .addPathPatterns("/logout/**")
.addPathPatterns("/authz/refused") .addPathPatterns("/authz/refused")
.excludePathPatterns("/logon/oauth20/**/**")
.excludePathPatterns("/swagger-ui/**") .excludePathPatterns("/swagger-ui/**")
.excludePathPatterns("/swagger-resources/**") .excludePathPatterns("/swagger-resources/**")
.excludePathPatterns("/v3/api-docs/**") .excludePathPatterns("/v3/api-docs/**")