Skip to content

Commit

Permalink
Merge pull request #158 from HereIsYui/master
Browse files Browse the repository at this point in the history
🎉新增扫码登录
  • Loading branch information
adlered authored Dec 4, 2024
2 parents f82948a + 7e52247 commit afdd845
Show file tree
Hide file tree
Showing 7 changed files with 427 additions and 186 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,12 @@
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/gif4j_zuixin_pojie1.jar</systemPath>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
<version>3.10.5.Final</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/b3log/symphony/processor/Router.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ public static void requestMapping() {
final LogsChannel logsChannel = beanManager.getReference(LogsChannel.class);
Dispatcher.webSocket("/logs-channel", logsChannel);

final LoginChannel loginChannel = beanManager.getReference(LoginChannel.class);
Dispatcher.webSocket("/login-channel", loginChannel);

// 注册 HTTP 错误处理
final ErrorProcessor errorProcessor = beanManager.getReference(ErrorProcessor.class);
Dispatcher.error("/error/{statusCode}", errorProcessor::handle);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.b3log.symphony.processor.channel;

import org.b3log.latke.http.WebSocketChannel;
import org.b3log.latke.http.WebSocketSession;
import org.b3log.latke.ioc.Singleton;
import org.json.JSONObject;

import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
/**
* Login channel.
*
* @author <a href="https://fishpi.cn/member/Yui">Yui</a>
* @version 1.0.0.0, Dec 4, 2024
*/
@Singleton
public class LoginChannel implements WebSocketChannel {
/**
* 已经连接的WebSocket客户端列表
*/
private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();

@Override
public void onConnect(WebSocketSession webSocketSession) {
// 把客户端存入Map,方便发信息
sessions.put(webSocketSession.getId(), webSocketSession);
}

@Override
public void onMessage(Message message) {
try {
JSONObject jsonObject = new JSONObject(message.text);
String targetId;
String apiKey;
WebSocketSession targetSession;
switch (jsonObject.get("type").toString()) {
case "1":
// type1: 获取web端websocket id 方便 APP 单独向指定的web发送apikey
message.session.sendText("targetId:" + message.session.getId());
break;
case "2":
// type2: APP 携带apiKey发送登录
targetId = jsonObject.get("targetId").toString();
apiKey = jsonObject.get("apiKey").toString();
if (targetId == null) {
message.session.sendText("{\"code\":1,\"msg\":\"Params is not right\"}");
break;
}
targetSession = sessions.get(targetId);
if (targetSession != null) {
targetSession.sendText("apiKey:" + apiKey);
message.session.sendText("{\"code\":0,\"msg\":\"Success\"}");
} else {
message.session.sendText("{\"code\":1,\"msg\":\"Target is not exist\"}");
}
break;
case "3":
// type3: APP 已经扫码,但是还没调用登录 (后续APP如果加点击确认按钮了,这个是中间状态)
targetId = jsonObject.get("targetId").toString();
if (targetId == null) {
message.session.sendText("{\"code\":1,\"msg\":\"Params is not right\"}");
break;
}
targetSession = sessions.get(targetId);
if (targetSession != null) {
targetSession.sendText("scan:ing~");
message.session.sendText("{\"code\":0,\"msg\":\"Success\"}");
} else {
message.session.sendText("{\"code\":1,\"msg\":\"Target is not exist\"}");
}
default:
break;
}
} catch (Exception e) {
message.session.sendText("{\"code\":1,\"msg\":\"Message parse error\"}");
}
}

@Override
public void onClose(WebSocketSession webSocketSession) {
// 将关闭连接的websocket从Map中移除
sessions.remove(webSocketSession.getId());
}

@Override
public void onError(Error error) {
}
}
2 changes: 1 addition & 1 deletion src/main/resources/css/index.css

Large diffs are not rendered by default.

170 changes: 112 additions & 58 deletions src/main/resources/js/verify.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ var Verify = {
*/
login: function (goto) {
goto = decodeURIComponent(goto)
if (Validate.goValidate({target: $('#loginTip'),
if (Validate.goValidate({
target: $('#loginTip'),
data: [{
"target": $("#nameOrEmail"),
"type": "string",
"max": 256,
"msg": Label.loginNameErrorLabel
}]})) {
"target": $("#nameOrEmail"),
"type": "string",
"max": 256,
"msg": Label.loginNameErrorLabel
}]
})) {
var requestJSONObject = {
nameOrEmail: $("#nameOrEmail").val().replace(/(^\s*)|(\s*$)/g, ""),
userPassword: calcMD5($("#loginPassword").val()),
Expand All @@ -63,11 +65,11 @@ var Verify = {
if (result.needCaptcha && "" !== result.needCaptcha) {
$('#captchaImg').parent().show();
$("#captchaImg").attr("src", Label.servePath + "/captcha/login?needCaptcha="
+ result.needCaptcha + "&t=" + Math.random())
.click(function () {
$(this).attr('src', Label.servePath + "/captcha/login?needCaptcha="
+ result.needCaptcha + "&t=" + Math.random())
});
+ result.needCaptcha + "&t=" + Math.random())
.click(function () {
$(this).attr('src', Label.servePath + "/captcha/login?needCaptcha="
+ result.needCaptcha + "&t=" + Math.random())
});
}
}
}
Expand All @@ -78,17 +80,19 @@ var Verify = {
* @description Register Step 1
*/
register: function () {
if (Validate.goValidate({target: $("#registerTip"),
if (Validate.goValidate({
target: $("#registerTip"),
data: [{
"target": $("#registerUserName"),
"msg": Label.invalidUserNameLabel,
"type": 'string',
'max': 20
}, {
"target": $("#registerUserPhone"),
"msg": "手机号码不合法",
"type": "phone"
}]})) {
"target": $("#registerUserName"),
"msg": Label.invalidUserNameLabel,
"type": 'string',
'max': 20
}, {
"target": $("#registerUserPhone"),
"msg": "手机号码不合法",
"type": "phone"
}]
})) {
var requestJSONObject = {
userName: $("#registerUserName").val().replace(/(^\s*)|(\s*$)/g, ""),
userPhone: $("#registerUserPhone").val().replace(/(^\s*)|(\s*$)/g, ""),
Expand Down Expand Up @@ -134,18 +138,20 @@ var Verify = {
* @description Register Step 2
*/
register2: function () {
if (Validate.goValidate({target: $("#registerTip2"),
if (Validate.goValidate({
target: $("#registerTip2"),
data: [{
"target": $("#registerUserPassword2"),
"msg": Label.invalidPasswordLabel,
"type": 'password',
'max': 20
}, {
"target": $("#registerConfirmPassword2"),
"original": $("#registerUserPassword2"),
"msg": Label.confirmPwdErrorLabel,
"type": "confirmPassword"
}]})) {
"target": $("#registerUserPassword2"),
"msg": Label.invalidPasswordLabel,
"type": 'password',
'max': 20
}, {
"target": $("#registerConfirmPassword2"),
"original": $("#registerUserPassword2"),
"msg": Label.confirmPwdErrorLabel,
"type": "confirmPassword"
}]
})) {
var requestJSONObject = {
userAppRole: $("input[name=userAppRole]:checked").val(),
userPassword: calcMD5($("#registerUserPassword2").val()),
Expand Down Expand Up @@ -178,17 +184,19 @@ var Verify = {
* @description Forget password
*/
forgetPwd: function () {
if (Validate.goValidate({target: $("#fpwdTip"),
if (Validate.goValidate({
target: $("#fpwdTip"),
data: [{
"target": $("#fpwdPhone"),
"msg": "手机号码不合法",
"type": "phone"
}, {
"target": $("#fpwdSecurityCode"),
"msg": Label.captchaErrorLabel,
"type": 'string',
'max': 4
}]})) {
"target": $("#fpwdPhone"),
"msg": "手机号码不合法",
"type": "phone"
}, {
"target": $("#fpwdSecurityCode"),
"msg": Label.captchaErrorLabel,
"type": 'string',
'max': 4
}]
})) {
var requestJSONObject = {
userPhone: $("#fpwdPhone").val(),
captcha: $("#fpwdSecurityCode").val()
Expand Down Expand Up @@ -224,18 +232,20 @@ var Verify = {
* @description Reset password
*/
resetPwd: function () {
if (Validate.goValidate({target: $("#rpwdTip"),
if (Validate.goValidate({
target: $("#rpwdTip"),
data: [{
"target": $("#rpwdUserPassword"),
"msg": Label.invalidPasswordLabel,
"type": 'password',
'max': 20
}, {
"target": $("#rpwdConfirmPassword"),
"original": $("#rpwdUserPassword"),
"msg": Label.confirmPwdErrorLabel,
"type": "confirmPassword"
}]})) {
"target": $("#rpwdUserPassword"),
"msg": Label.invalidPasswordLabel,
"type": 'password',
'max': 20
}, {
"target": $("#rpwdConfirmPassword"),
"original": $("#rpwdUserPassword"),
"msg": Label.confirmPwdErrorLabel,
"type": "confirmPassword"
}]
})) {
var requestJSONObject = {
userPassword: calcMD5($("#rpwdUserPassword").val()),
userId: $("#rpwdUserId").val(),
Expand Down Expand Up @@ -346,7 +356,7 @@ var Verify = {
sortBy: step2Sort
});
step2Sort = (step2Sort === 'random' ? 'original-order' : 'random');
$('.tag-desc').on( 'arrangeComplete', function () {
$('.tag-desc').on('arrangeComplete', function () {
$('.step-btn .green, .step-btn .red').prop('disabled', false);
});
if ($('.tag-desc li').length < 2) {
Expand All @@ -362,11 +372,11 @@ var Verify = {
$('.guide-tab > div:eq(3)').show();
$('.intro dt:eq(3)').addClass('current');

$('.step-btn .red').show();
$('.step-btn .green').text(Label.nextStepLabel);
$('.step-btn .red').show();
$('.step-btn .green').text(Label.nextStepLabel);

$('.intro > div').hide();
$('.intro > dl').show();
$('.intro > div').hide();
$('.intro > dl').show();
break;
case 5:
$('.guide-tab > div:eq(4)').show();
Expand Down Expand Up @@ -425,5 +435,49 @@ var Verify = {
$('.tag-desc li:eq(' + random + ')').addClass('current');
Util.follow(window, $('.tag-desc li:eq(' + random + ')').data('id'), 'tag');

},
/**
* 初始化二维码登录
*
* */
loginSocket: null,
initQrCodeLogin: function () {
this.loginSocket = new WebSocket('ws://localhost:8080/login-channel');
this.loginSocket.onopen = (event) => {
console.log('连接打开');
this.loginSocket.send(JSON.stringify({
type: 1,
}))
};

this.loginSocket.onmessage = function (event) {
console.log('收到消息:', event.data);
let msg = event.data;
try {
let imgObj = document.querySelector("#qrcode_img");
if (msg.indexOf("targetId") === 0) {
imgObj.src = "https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=web:" + msg.split(':')[1];
} else if (msg.indexOf("apiKey") === 0) {
window.location.href = Label.servePath + "/loginWebInApiKey?apiKey=" + msg.split(':')[1];
}else if(msg.indexOf("scan") === 0){
let boxObj = document.querySelector("#login-qrcode-div");
boxObj.classList.add("scan-ing")
}
} catch (e) {

}
}

this.loginSocket.onclose = (event)=> {
console.log('WebSocket 连接已关闭');
};

this.loginSocket.onerror = (error) =>{
console.log('WebSocket 出现错误:', error);
this.loginSocket.close();
};
},
closeQrCodeLogin: function () {
this.loginSocket.close();
}
};
Loading

0 comments on commit afdd845

Please sign in to comment.