对接界面操作与VMS网络接口,实现注册登录操作;规范用户名、注册用户名、身份标识名、密码、注册密码之间的区别和联系(参见README.md)

This commit is contained in:
free will
2021-07-29 20:18:04 +08:00
parent 39b6588221
commit 9237f63f07
13 changed files with 99 additions and 71 deletions
+12 -1
View File
@@ -1,4 +1,4 @@
# MIN-VPN-Client
# MIN-VPN-Client项目说明
## 项目开发背景说明
本项目前身是MIN-VPN-Android的V2master分支。
@@ -27,3 +27,14 @@
## 使用说明
导出APK,安装到安卓手机,即可使用
# MIN-VPN-Client开发说明
## 用户名及密码说明
用户输入的用户名将永远不作为项目中代码运行使用的用户名而存在,以避免前后端交互时因编码问题而出现BUG,
例如,用户输入的用户名RawUsername为:“张三”,
则项目中的用户名则为其经过base64编码后的Username"5byg5LiJ"
而标识则使用再次经过base64编码后然后前面加上"/"的IdentityName"/NWJ5ZzVMaUo-"
可以看出,其中的Username和IdentityName均与用户注册时输入的用户名有关,但不是同一个字符串。
密码也是同理,代码运行时候的密码passwd是用户输入的原始密码RawPasswd经过md5哈希之后得到。
MINVpnSettingAPI中的用户名和密码是用户输入的RawUsername和RawPasswd,在注册和登录时再进行处理。
@@ -14,18 +14,16 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.google.android.material.checkbox.MaterialCheckBox;
import com.pkusz.min_vpn_client.GlobalSetting;
import com.pkusz.min_vpn_client.R;
import com.pkusz.min_vpn_client.activity.base.MINVpnBaseActivity;
import com.pkusz.min_vpn_client.activity.main.MainActivity;
import com.pkusz.min_vpn_client.activity.register.RegisterActivity;
import com.pkusz.min_vpn_client.activity.setting.SettingActivity;
import com.pkusz.min_vpn_client.model.MINVpnSettingAPI;
import com.pkusz.min_vpn_client.model.request.OriginalLoginRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalLoginRequest;
import com.pkusz.min_vpn_client.utils.AccountValidatorRegexUtil;
import com.pkusz.min_vpn_client.utils.Base64Util;
import com.pkusz.min_vpn_client.utils.DigestUtilKt;
import com.pkusz.min_vpn_client.utils.KeyManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -47,8 +45,8 @@ import kotlin.jvm.functions.Function1;
public class LoginActivity extends MINVpnBaseActivity<LoginActivityPresenter>
implements LoginActivityContract.View{
// 常规变量区
private String username="";
private String password="";
private String rawUsername ="";
private String rawPassword ="";
// 界面变量区
private EasyBar easyBar;
private ImageView imageView_imgLogo;
@@ -143,47 +141,44 @@ public class LoginActivity extends MINVpnBaseActivity<LoginActivityPresenter>
ContextExtensionKt.hideSoftKeyboard(this,btnLogin);
btnLogin.startAnimation();
this.username= Objects.requireNonNull(etUsername.getText()).toString();
this.password= Objects.requireNonNull(etPassword.getText()).toString();
this.rawUsername = Objects.requireNonNull(etUsername.getText()).toString();
this.rawPassword = Objects.requireNonNull(etPassword.getText()).toString();
boolean testFlag=true;
if(!testFlag){
if (username.isEmpty() || password.isEmpty()) {
// boolean testFlag=true;
// if(!testFlag){
if (rawUsername.isEmpty() || rawPassword.isEmpty()) {
showWarning("请将信息填写完整");
btnLogin.revertAnimation();
return;
}
if (!AccountValidatorRegexUtil.INSTANCE.isPassword(password)) {
if (!AccountValidatorRegexUtil.INSTANCE.isPassword(rawPassword)) {
showWarning("请输入有效的密码,密码为8-16位,必须包含大小写字母和特殊符号");
btnLogin.revertAnimation();
return;
}
if (!AccountValidatorRegexUtil.INSTANCE.isUsername(username)) {
if (!AccountValidatorRegexUtil.INSTANCE.isUsername(rawUsername)) {
showWarning("请输入有效的用户名,用户名长度需要大于0小于20");
btnLogin.revertAnimation();
return;
}
// 账号转base64
// 用户名经base64编码
String username;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
username = Base64Util.Base64PlusEncode(username);
username = Base64Util.Base64PlusEncode(rawUsername);
} else {
System.out.println("Base64Util.Base64PlusDecode error");
btnLogin.revertAnimation();
return;
}
}
// 初始化keymanager
KeyManager.INSTANCE.initKeyChain("/"+username);
// 密码经md5哈希
String password =DigestUtilKt.encodeToMD5(rawPassword);
// }
// 登录server(密码转md5)
OriginalLoginRequest loginRequest=new OriginalLoginRequest(username,
DigestUtilKt.encodeToMD5(password));
if(GlobalSetting.openBiometric){
// 第一种模式,人脸识别登录,暂时废弃
// mPresenter.downloadRegisterFacePicture(username,loginRequest,this);
}else{
mPresenter.login(loginRequest);
}
// 传递登录请求信息,执行登录网络请求
OriginalLoginRequest loginRequest=new OriginalLoginRequest(username, password);
mPresenter.login(loginRequest);
});
// 监听键盘是否弹起
@@ -215,13 +210,8 @@ public class LoginActivity extends MINVpnBaseActivity<LoginActivityPresenter>
}
return null;
});
}
@NotNull
@Override
public LoginActivityPresenter onCreatePresenter() {
@@ -236,9 +226,9 @@ public class LoginActivity extends MINVpnBaseActivity<LoginActivityPresenter>
@Override
public void loginSuccess(String successMsg) {
showSuccess(successMsg);
MINVpnSettingAPI.INSTANCE.updateUsername(username);
MINVpnSettingAPI.INSTANCE.updateUsername(rawUsername);
if(savePasswordBox.isChecked()){
MINVpnSettingAPI.INSTANCE.updatePassword(password);
MINVpnSettingAPI.INSTANCE.updatePassword(rawPassword);
}else{
MINVpnSettingAPI.INSTANCE.updatePassword("");
}
@@ -10,7 +10,7 @@ package com.pkusz.min_vpn_client.activity.login;
import android.content.Context;
import com.pkusz.min_vpn_client.activity.base.MINVpnBaseView;
import com.pkusz.min_vpn_client.model.request.OriginalLoginRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalLoginRequest;
import cn.qjm253.quick_android_mvp.base.mvp.BaseModel;
import cn.qjm253.quick_android_mvp.base.mvp.BasePresenter;
@@ -9,7 +9,8 @@ package com.pkusz.min_vpn_client.activity.login;
import android.content.Context;
import com.pkusz.min_vpn_client.model.request.OriginalLoginRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalLoginRequest;
import com.pkusz.min_vpn_client.model.VMSRequestAPI;
import common.LoggerHelper;
@@ -22,30 +23,23 @@ public class LoginActivityModel implements LoginActivityContract.Model{
@Override
public void login(OriginalLoginRequest loginRequest) {
// 与MIS通信,获取返回信息
// Request_API.INSTANCE.login()
// 假定成功登录,则执行下面语句
boolean flag=true;
if(flag){
Integer resCode= VMSRequestAPI.INSTANCE.login(loginRequest);
if(resCode==200) {
mPresenter.loginSuccess();
}else{
mPresenter.loginFailed("测试登录失败...");
mPresenter.loginFailed("登录失败VMS应答码为"+resCode);
}
}
@Override
public void loginWithSafetyInfo(OriginalLoginRequest loginRequest, Context context) {
// 内含百度定位、mac地址等信息
boolean flag=true;
if(flag){
mPresenter.loginSuccess();
}else{
mPresenter.loginFailed("测试登录失败...");
}
// 废弃接口
LoggerHelper.warning("model.loginWithSafetyInfo: 暂停使用含有mac地址等安全信息的登录功能");
}
@Override
public void downloadRegisterFacePicture(String username, OriginalLoginRequest loginRequest, Context context) {
// 废弃接口
LoggerHelper.warning("model.downloadRegisterFacePicture: 暂停人脸识别登录功能");
}
}
@@ -9,7 +9,7 @@ package com.pkusz.min_vpn_client.activity.login;
import android.content.Context;
import com.pkusz.min_vpn_client.model.request.OriginalLoginRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalLoginRequest;
public class LoginActivityPresenter extends LoginActivityContract.Presenter{
public LoginActivityPresenter(LoginActivity loginActivity){
@@ -16,9 +16,10 @@ import android.widget.Toast;
import com.pkusz.min_vpn_client.R;
import com.pkusz.min_vpn_client.activity.base.MINVpnBaseActivity;
import com.pkusz.min_vpn_client.activity.login.LoginActivity;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalRegisterRequest;
import com.pkusz.min_vpn_client.utils.AccountValidatorRegexUtil;
import com.pkusz.min_vpn_client.utils.Base64Util;
import com.pkusz.min_vpn_client.utils.KeyManager;
import com.pkusz.min_vpn_client.utils.DigestUtilKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -152,21 +153,23 @@ public class RegisterActivity extends MINVpnBaseActivity<RegisterActivityPresent
return;
}
// 用户名经base64编码
String base64Username;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
username= Base64Util.Base64PlusEncode(username);
}else{
showWarning("username base64 error");
base64Username = Base64Util.Base64PlusEncode(username);
} else {
System.out.println("Base64Util.Base64PlusDecode error");
btnRegister.revertAnimation();
return;
}
System.out.println("username: "+username);
// todo: 这里存疑
byte[] certification= KeyManager.INSTANCE.initKeyChain("/"+username)
.getCertification("/"+username).getSignature();
// todo: 发送注册信息
// 密码经md5哈希
String md5Password = DigestUtilKt.encodeToMD5(password);
// 传递注册请求信息,执行注册网络请求
OriginalRegisterRequest original=new OriginalRegisterRequest(
base64Username,md5Password,phone,email,inviteCode);
mPresenter.register(original);
});
// 监听键盘是否弹起
@@ -10,7 +10,7 @@ package com.pkusz.min_vpn_client.activity.register;
import android.content.Context;
import com.pkusz.min_vpn_client.activity.base.MINVpnBaseView;
import com.pkusz.min_vpn_client.model.request.OriginalRegisterRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalRegisterRequest;
import cn.qjm253.quick_android_mvp.base.mvp.BaseModel;
import cn.qjm253.quick_android_mvp.base.mvp.BasePresenter;
@@ -9,7 +9,10 @@ package com.pkusz.min_vpn_client.activity.register;
import android.content.Context;
import com.pkusz.min_vpn_client.model.request.OriginalRegisterRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalRegisterRequest;
import com.pkusz.min_vpn_client.model.VMSRequestAPI;
import common.LoggerHelper;
public class RegisterActivityModel implements RegisterActivityContract.Model{
private RegisterActivityPresenter mPresenter;
@@ -19,16 +22,23 @@ public class RegisterActivityModel implements RegisterActivityContract.Model{
@Override
public void register(OriginalRegisterRequest registerRequest) {
mPresenter.registerSuccess();
Integer resCode=VMSRequestAPI.INSTANCE.register(registerRequest);
if(resCode==200) {
mPresenter.registerSuccess();
}else{
mPresenter.registerFailed("注册失败,VMS应答码为"+resCode);
}
}
@Override
public void registerWithSafetyInfo(OriginalRegisterRequest registerRequest, Context context) {
mPresenter.registerSuccess();
// 废弃接口
LoggerHelper.warning("model.registerWithSafetyInfo: 暂停使用含有mac地址等安全信息的注册功能");
}
@Override
public void uploadRegisterFacePicture(String username, OriginalRegisterRequest registerRequest, Context context) {
// 废弃接口
// 废弃接口
LoggerHelper.warning("model.uploadRegisterFacePicture: 暂停人脸识别注册功能");
}
}
@@ -9,7 +9,7 @@ package com.pkusz.min_vpn_client.activity.register;
import android.content.Context;
import com.pkusz.min_vpn_client.model.request.OriginalRegisterRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalRegisterRequest;
public class RegisterActivityPresenter extends RegisterActivityContract.Presenter{
public RegisterActivityPresenter(RegisterActivity registerActivity){
@@ -1,4 +1,4 @@
package com.pkusz.min_vpn_client.model.request;
package com.pkusz.min_vpn_client.model.OriginalRequest;
/*
* @Author: Wang Feng
* @Description: 登录请求的原始属性
@@ -1,4 +1,4 @@
package com.pkusz.min_vpn_client.model.request;
package com.pkusz.min_vpn_client.model.OriginalRequest;
/*
* @Author: Wang Feng
* @Description: 注册请求的原始属性
@@ -8,8 +8,8 @@ package com.pkusz.min_vpn_client.model;
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
import com.pkusz.min_vpn_client.model.request.OriginalLoginRequest;
import com.pkusz.min_vpn_client.model.request.OriginalRegisterRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalLoginRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalRegisterRequest;
import com.pkusz.min_vpn_client.utils.KeyManager;
import org.bouncycastle.crypto.CryptoException;
@@ -0,0 +1,20 @@
package com.pkusz.min_vpn_client.model;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 19:28 2021/7/29
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
import com.pkusz.min_vpn_client.utils.Base64Util;
import org.junit.Test;
public class TestBase64 {
@Test
public void testBasePlus64(){
System.out.println(Base64Util.Base64PlusEncode("张三"));
System.out.println(Base64Util.Base64PlusEncode(Base64Util.Base64PlusEncode("张三")));
}
}