首页登陆替换成Google身份验证器

新增配置工具类
更新页面
This commit is contained in:
Yutousama 2020-09-29 08:52:16 +08:00
parent 11bbd3642e
commit 71d8a52dec
9 changed files with 325 additions and 40 deletions

View File

@ -10,7 +10,7 @@
</parent>
<groupId>com.yutou</groupId>
<artifactId>tools</artifactId>
<version>1.0.8</version>
<version>1.0.9.1</version>
<name>tools</name>
<description>Demo project for Spring Boot</description>

View File

@ -10,12 +10,13 @@ import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base64;
public class GoogleAccount {
public static final boolean isDev=false;
// 生成的key长度( Generate secret key length)
public static final int SECRET_SIZE = 10;
private static final int SECRET_SIZE = 10;
public static final String SEED = "g8GjEvTbW5oVSV7avL47357438reyhreyuryetredLDVKs2m0QN7vxRs2im5MDaNCWGmcD2rvcZx";
private static final String SEED = "g8GjEvTbW5oVSV7avL47357438reyhreyuryetredLDVKs2m0QN7vxRs2im5MDaNCWGmcD2rvcZx";
// Java实现随机数算法
public static final String RANDOM_NUMBER_ALGORITHM = "SHA1PRNG";
private static final String RANDOM_NUMBER_ALGORITHM = "SHA1PRNG";
// 最多可偏移的时间
int window_size = 3; // default 3 - max 17
@ -145,7 +146,8 @@ public class GoogleAccount {
public static void main(String[] args) {
String secret=GoogleAccount.generateSecretKey();
String qrcode = GoogleAccount.getQRBarcode("yutou", secret);
String uname=isDev?"yutou(dev)":"yutou";
String qrcode = GoogleAccount.getQRBarcode(uname, secret);
System.out.println("qrcode:" + qrcode + ",key:" + secret);
while (true){
String code=new Scanner(System.in).nextLine();

View File

@ -0,0 +1,81 @@
package com.yutou.tools.services;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
public class ServerManager {
private static ServerManager manager;
private ServerSocket server;
private ServerManager(){
try {
server=new ServerSocket(8100);
while (true){
new MyThread(server.accept());
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void restart(){
try {
server.close();
}catch (Exception e){
e.printStackTrace();
}
try {
server=new ServerSocket(8100);
} catch (IOException e) {
e.printStackTrace();
}
}
private OutputStream nasOutPutStream;
private InputStream nasInputStream;
public static ServerManager getManager() {
if(manager==null){
manager=new ServerManager();
}
return manager;
}
public void send(String msg){
if(nasOutPutStream!=null){
try {
nasOutPutStream.write(msg.getBytes());
nasOutPutStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class MyThread extends Thread{
Socket socket;
private MyThread(Socket socket){
this.socket=socket;
start();
}
@Override
public void run() {
super.run();
try {
nasOutPutStream=socket.getOutputStream();
nasInputStream=socket.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(nasInputStream));
String tmp,str="";
while (true){
tmp=reader.readLine();
if(tmp!=null){
System.out.println(tmp);
}
}
} catch (IOException e) {
e.printStackTrace();
}
nasOutPutStream=null;
nasInputStream=null;
}
}
}

View File

@ -0,0 +1,79 @@
package com.yutou.tools.utils;
import com.alibaba.fastjson.JSONObject;
import java.io.*;
/**
* 配置和参数
*/
public class ConfigTools {
public static final String CONFIG="config.json";
public static final String DATA="data.json";
static {
try {
File file=new File(CONFIG);
if(!file.exists()){
file.createNewFile();
}
file=new File(DATA);
if(!file.exists()){
file.createNewFile();
}
file=null;
}catch (Exception e){
e.printStackTrace();
}
}
public static Object load(String type,String key){
File file=new File(type);
String src=readFile(file);
if(src!=null){
JSONObject json=JSONObject.parseObject(src);
if(json==null){
json=new JSONObject();
saveFile(file,json.toJSONString());
}
return json.getOrDefault(key, "");
}
return null;
}
public static boolean save(String type,String key,Object data){
File file=new File(type);
String src=readFile(file);
if(src!=null){
JSONObject json=JSONObject.parseObject(src);
json.put(key,data);
saveFile(file,json.toJSONString());
}
return false;
}
public static boolean saveFile(File file,String data){
try {
FileWriter writer=new FileWriter(file);
writer.write(data);
writer.flush();
writer.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static String readFile(File file){
try {
BufferedReader reader=new BufferedReader(new FileReader(file));
String tmp;
StringBuilder str= new StringBuilder();
while ((tmp=reader.readLine())!=null){
str.append(tmp);
}
reader.close();
return str.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -226,6 +226,9 @@ public class RedisTools {
case "cmd":
system("cmd", message);
break;
case "msg":
Tools.sendServer("来自服务姬的通知~",message);
break;
}
}
@ -260,7 +263,19 @@ public class RedisTools {
}
}
private void processOut(InputStream inputStream) {
private void bot(String value) {
switch (value) {
case "getip":
JSONObject json = JSONObject.parseObject(Tools.get("https://api.asilu.com/ip/"));
String ip = json.getString("ip");
RedisTools.set(1, "msg_" + System.currentTimeMillis(), "服务器IP:\n" + ip);
break;
}
}
}
public static void processOut(InputStream inputStream) {
String tmp, str = "null";
try {
@ -277,18 +292,6 @@ public class RedisTools {
RedisTools.set(1, "msg_" + System.currentTimeMillis(), str);
System.out.println("线程结束");
}
private void bot(String value) {
switch (value) {
case "getip":
JSONObject json = JSONObject.parseObject(Tools.get("https://api.asilu.com/ip/"));
String ip = json.getString("ip");
RedisTools.set(1, "msg_" + System.currentTimeMillis(), "服务器IP:\n" + ip);
break;
}
}
}
public static void main(String[] args) {
RedisTools.pullMsg("msg", "abc");
}

View File

@ -0,0 +1,45 @@
package com.yutou.tools.web;
import com.yutou.tools.nas.UpdateIp;
import com.yutou.tools.utils.RedisTools;
import com.yutou.tools.utils.Tools;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@Controller
public class ToolsController {
@ResponseBody
@RequestMapping("/tools/openpc.do")
public String open_pc(HttpServletRequest request, String type) {
if (StringUtils.isEmpty(type)) {
if (Tools.checkWebLogin(request) == 1) {
Tools.get("http://" + UpdateIp.nas_ip + ":8000/tools/openpc.do?token=zIrsh9TUZP2lfRW753PannG49E7VJvor&type=nas");
}
} else {
if (type.equals("nas")) {
try {
Process process = Runtime.getRuntime().exec("wakeonlan 00:D8:61:6F:02:2F");
RedisTools.processOut(process.getInputStream());
RedisTools.processOut(process.getErrorStream());
process.destroy();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "ok";
}
@ResponseBody
@RequestMapping("/tools/server.do")
public String sendServerManager(String title, String msg) {
Tools.sendServer(title, msg);
return "ok";
}
}

View File

@ -3,9 +3,12 @@ package com.yutou.tools.web;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yutou.tools.Tools.GoogleAccount;
import com.yutou.tools.utils.ConfigTools;
import com.yutou.tools.utils.RedisTools;
import com.yutou.tools.utils.Tools;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@ -56,14 +59,17 @@ public class userController {
@ResponseBody
public String captcha(HttpServletRequest request) {
JSONArray array = new JSONArray();
JSONObject json = new JSONObject();
if (RedisTools.get("ban") != null) {
array = JSONArray.parseArray(RedisTools.get("ban"));
}
if (array.contains(Tools.getRemoteAddress(request))) {
System.out.println("IP已被封禁");
return "ERROR!";
json.put("msg", "IP已被封禁");
json.put("code", -1);
return json.toJSONString();
}
/* //原验证码方案
int[] captcha = Tools.randomCommon(0, 9, 6);
String cc = "";
for (int value : captcha) {
@ -75,8 +81,21 @@ public class userController {
String url = "http://tools.yutou233.cn/login/ban.do?token=" + token;
Tools.sendServer("管理后台登录验证码", "本次登录验证码为:" + cc
+ ",登录IP:" + Tools.getRemoteAddress(request)
+ ",非正常登录封禁IP:" + url);
return "ok";
+ ",非正常登录封禁IP:" + url);*/
String secret = (String) ConfigTools.load(ConfigTools.DATA, "secret");
if (StringUtils.isEmpty(secret)) {
secret = GoogleAccount.generateSecretKey();
String uname=GoogleAccount.isDev?"yutou(dev)":"yutou";
String code = GoogleAccount.getQRBarcode(uname, secret);
ConfigTools.save(ConfigTools.DATA,"secret_tmp",secret);
json.put("msg", "绑定连接");
json.put("code", 1);
json.put("data", code);
return json.toJSONString();
}
json.put("msg", "ok");
json.put("code", 0);
return json.toJSONString();
}
@RequestMapping("/login/ban.do")
@ -88,8 +107,8 @@ public class userController {
if (RedisTools.get("ban") != null) {
array = JSONArray.parseArray(RedisTools.get("bean"));
}
if(array==null){
array=new JSONArray();
if (array == null) {
array = new JSONArray();
}
array.add(ip);
RedisTools.set("ban", array.toJSONString());
@ -107,7 +126,34 @@ public class userController {
@ResponseBody
public String login(HttpServletResponse response, String code) {
JSONObject json = new JSONObject();
if (RedisTools.get("login").equals(code.trim())) {
String secret= (String) ConfigTools.load(ConfigTools.DATA,"secret");
if(StringUtils.isEmpty(secret)){
secret= (String) ConfigTools.load(ConfigTools.DATA,"secret_tmp");
if(StringUtils.isEmpty(secret)){
json.put("code",-2);
json.put("msg","未绑定");
return json.toJSONString();
}
if(new GoogleAccount().check_code(secret,Long.parseLong(code),System.currentTimeMillis())){
json.put("code", 0);
json.put("msg", "登录成功");
ConfigTools.save(ConfigTools.DATA,"secret",secret);
ConfigTools.save(ConfigTools.DATA,"secret_tmp","");
}else {
json.put("code", -2);
json.put("msg", "登录失败");
return json.toJSONString();
}
}else{
if(new GoogleAccount().check_code(secret,Long.parseLong(code),System.currentTimeMillis())){
json.put("code", 0);
json.put("msg", "登录成功");
}else {
json.put("code", -2);
json.put("msg", "登录失败");
return json.toJSONString();
}
}
String uuid = UUID.randomUUID().toString();
Tools.setCookie(response, "user", uuid.replace("-", ""), 30 * 24 * 60 * 60);
RedisTools.set(uuid.replace("-", ""), "ok", 30 * 24 * 60 * 60);
@ -115,10 +161,6 @@ public class userController {
json.put("msg", "登录成功");
return json.toJSONString();
}
json.put("code", -2);
json.put("msg", "登录安全码错误");
return json.toJSONString();
}
@RequestMapping(value = "/login/logout.do", method = RequestMethod.POST)
@ResponseBody

View File

@ -19,6 +19,7 @@
<a href="javascript:;">工具集</a>
<dl class="layui-nav-child">
<dd><a href="/html/body/tools/password.html">密码管理器</a></dd>
<dd><a href="javascript:;" id="open_pc">远程开机</a></dd>
</dl>
</li>
<li class="layui-nav-item">
@ -38,11 +39,12 @@
</ul>
</div>
</body>
<script src="../js/qrcode.min.js"></script>
<script>
let loginStatus = false;
$.get("/login/check.do", function (data) {
let json = JSON.parse(data);
if (json.code == 0) {
if (json.code === 0) {
$('#login_text').text('已登录')
loginStatus = true;
}
@ -51,7 +53,27 @@
if (loginStatus) {
return;
}
$.post('/login/sendCaptcha.do', function () {
$.post('/login/sendCaptcha.do', function (data) {
let json=JSON.parse(data);
if(json.code===1){
layer.open({
title:"使用Google身份验证器绑定",
content:"<div id=\"qrcode\"></div>",
success:function () {
new QRCode(document.getElementById("qrcode"), json.data);
},
yes:function (index) {
layer.close(index)
openLoginCode();
}
})
}else{
openLoginCode();
}
})
function openLoginCode() {
layer.prompt({
title: '安全登录码'
}, function (value, index, elem) {
@ -62,7 +84,7 @@
});
layer.close(index);
})
})
}
})
$('#logout').click(function () {
$.post('/login/logout.do', function (data) {
@ -70,6 +92,16 @@
layer.msg(json.msg)
window.location.href = "/"
})
});
$('#open_pc').click(function () {
layer.open({
title:"msg",
content: "确定开机?",
yes:function (index) {
$.post("/tools/openpc.do");
layer.close(index)
}
})
})
$(document).ready(function () {
let mobile = navigator.userAgent.toLowerCase().match(/android/i) == "android" || navigator.userAgent.toLowerCase().match(/iphone os/i) == "iphone os";

1
web/js/qrcode.min.js vendored Normal file

File diff suppressed because one or more lines are too long