如何写一个安全的手机验证码登录功能

直接画了张简单的示例图进行展示最终效果。

用户输入手机号码,激活码(可以理解为一个约束条件)后,点击获取验证码,向后台发送验证码请求,就可以从后台返回一个验证码哈希值(暂且定义为:et_token),后台请求短信验证码发送到用户手机上。用户填写验证码后,就可以点击登录,登录的时候发送手机验证码和et_token校验请求
如何写一个安全的手机验证码登录功能_第1张图片
所以总共需要发送两个请求。

请求方式是使用Xutils已经封装好的的http请求。可以点击查看:Android请求服务器获取短信验证码实现注册功能里面介绍的挺详细的。

这里需要注意三个地方:
第一点:Xutils网络请求,根据官网说明:在application中初始化:

x.Ext.setDebug(BuildConfig.DEBUG)//是否输出debug日志, 开启debug会影响性能.

或者添加以下代码来输出请求日志:

RequestParams params = new RequestParams("请求地址");
String str = String.valueOf(type);
//需要携带的参数
params.addBodyParameter("phone", phoneNumber);//手机号
params.addBodyParameter("type", mEt_Code);//激活码
params.setRequestTracker(new RequestTracker() {
    @Override
    public void onWaiting(RequestParams params) {

    }

    @Override
    public void onStart(RequestParams params) {

    }

    @Override
    public void onRequestCreated(UriRequest request) {

    }

    @Override
    public void onCache(UriRequest request, Object result) {

    }

    @Override
    public void onSuccess(UriRequest request, Object result) {
        Log.d(TAG, "onSuccess: 获取验证码UriRequest成功:"+result.toString());

    }

    @Override
    public void onCancelled(UriRequest request) {

    }

    @Override
    public void onError(UriRequest request, Throwable ex, boolean isCallbackError) {

    }

    @Override
    public void onFinished(UriRequest request) {

    }
});

第二点:xutils的http请求回调接口有两种形式:根据项目需求选择

	//第一种
	 //这里的 new Callback.CacheCallback()是带有缓存数据功能的
    RequestParams params = getGLKTRequestParams(“接口地址”,map);
     x.http().post(params, new Callback.CacheCallback<String>()
	//第二种
	//new Callback.CommonCallback(),正常使用这种不带缓存回调
  RequestParams params = getGLKTRequestParams(requestCodeUrl, map);
  x.http().post(params, new Callback.CommonCallback<String>()

第三点:网络请求的安全加密
传入的参数使用Base64加密,签名文件使用:MD5加密

/**
     * MD5加密
     *
     * @param paramString
     * @return
     */
    private static String md5(String paramString) {
        String returnStr;
        try {
            MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
            localMessageDigest.update(paramString.getBytes());
            returnStr = byteToHexString(localMessageDigest.digest());
            return returnStr;
        } catch (Exception e) {
            return paramString;
        }
    }

    /**
     * 将指定byte数组转换成16进制字符串
     *
     * @param b
     * @return
     */
    private static String byteToHexString(byte[] b) {
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            //  hexString.append(hex.toUpperCase());
            hexString.append(hex.toLowerCase());
        }
        return hexString.toString();
    }

获取数据成功后需要使用Base64解密

/**
     * 获取响应dataString
     * @param result
     * @return
     */
    public static String getResponseDataBean(String result){
        return  new String(Base64.decode(gsonToBean(result,RDataBean.class).data, Base64.NO_WRAP));
    }

    public static <T> T gsonToBean(String gsonString, Class<T> cls) {
        Gson gson = new Gson();
        T t = gson.fromJson(gsonString, cls); //解释json字符串数据,返回是数据类型传入的类类型
        return t;
    }

    public class RDataBean {
        public String data;
        public String sign;
    }

你可能感兴趣的:(android进阶)