第三方单点登录的接口编写

结合自身项目中的一个案列来编写第三方单点登录接口,目的是让第三方系统调用我们的接口,无需再次登录,跳转到我们的系统,我们系统自动帮用户进行登录

这个接口需要写两个,第一个则需要生成token,token的作用是防止第三方恶意登录以及会话过期。结合我个人案列的场景,这个案例是图书馆,用户现在在第三方登录,跳到图书馆系统,调用我们这个接口。

这里使用des加密参数生成token。

代码如下,第一个接口:

/**
     * 校验身份和生成token
     *
     * @param cardNO 卡号
     * @param idcardNO 身份证号
     * @param signatrue 签名
     * @param timestamp 时间戳
     * @param type 登录设备类型
     * @return
     */
    @RequestMapping("/createToekn")
    @ResponseBody
    public ResultEntity createToken(String cardNO, String idcardNO, @RequestParam(required = true) String signatrue, @RequestParam(required = true) String timestamp, @RequestParam(required = true) String type) {
        //根据参数名进行排序
        SortedMap<String, String> parameterMap = new TreeMap<>();
        parameterMap.put("cardNO", cardNO);
        parameterMap.put("idcardNO", idcardNO);
        parameterMap.put("timestamp", timestamp);
        parameterMap.put("type", type);
        StringBuffer sb = new StringBuffer();
        Set es = parameterMap.entrySet();  //所有参与传参的参数按照accsii排序(升序)
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            Object v = entry.getValue();
            //空值不传递,不参与签名组串
            if (null != v && !"".equals(v)) {
                sb.append(v);
            }
        }
        ResultEntity result = new ResultEntity();
        //排序好的参数进行MD5加密
        String md5Str = MD5Util.md5(sb + secretKey);
        if (md5Str.equals(signatrue)) {
            //验证通过,使用des生成token返回
            //判断时间戳,超过120分钟,认证超时
            Long currTime = System.currentTimeMillis();
            if ((currTime - Long.parseLong(timestamp)) / (1000 * 60) > 120) { //这里设置签名只有两个小时有效时间,超过需要重新请求,这个第三方请求则需要将参数易进行accsii排序(升序),然后MD5加密,将sign传值过来再次认证
                result.setState(HttpCode.FAILED);
                result.setMessage("认证超时,请重新请求!");
                return result;
            }

            String jsonStr = JsonUtils.toJson(parameterMap);
            //使用des进行加密
            DESPlus des = new DESPlus();
            String token = des.encrypt(jsonStr);
            //返回token
            result.setResult(token);
            result.setMessage("认证通过!");
            result.setState(HttpCode.SUCCESS);
            return result;
        }
        result.setMessage("认证失败!");
        result.setState(HttpCode.FAILED);
        return result;
    }

第二个接口这需要验证token,验证通过了,则系统帮用户登录,验证不通过则跳到登录页面,让用户自行登录。

代码如下,第二个接口:

/**
     * 免密登录
     */
    @RequestMapping("/checkToken")
    public String checkToken(String token, HttpServletRequest request, HttpServletResponse response) {
        String cardNO = "";
        String idcardNO = "";
        String type = "";
        String timestamp = "";
        if (token != null && token != "") {
            try {
                //使用des解密
                DESPlus des = new DESPlus();
                String decStr = des.decrypt(token);
                //将字符串转换成map对象
                Map<String, String> parameterMap = new HashMap<String, String>();
                //将对象放到map中
                parameterMap = JsonUtils.fromJson(decStr, Map.class);
                cardNO = parameterMap.get("cardNO");
                idcardNO = parameterMap.get("idcardNO");
                type = parameterMap.get("type");
                timestamp = parameterMap.get("timestamp");
                //判断时间有没有超过120分钟,超过即失效,跳转到登录界面
                Long currTime = System.currentTimeMillis();
                if ((currTime - Long.parseLong(timestamp)) / (1000 * 60) > 120) {
                    //跳转到用户主页
                    if (type.equals("2")) {
                        //跳转到微信端的界面
                        return "mobile/index";
                    } else {
                        //默认跳转到pc端界面
                        return "pc/index";
                    }
                }
                if (cardNO != null || idcardNO != null) {
                    //根据卡号或者身份证号去数据库查询用户信息
                    ReaderEntity param = new ReaderEntity();
                    param.setCardno(cardNO);
                    param.setIdcardno(idcardNO);
                    List<ReaderEntity> readerEntities = readerDao.selectByParam(param);
                    if (!readerEntities.isEmpty()) {
                        //存入session中,并且判断type pc:1,微信:2,然后跳转到各自首页
                        //创建session对象
                        HttpSession session = request.getSession();
                        session.setAttribute(USES_SESSION_ID, readerEntities.get(0));
                        //跳转到用户主页
                        if (type.equals("2")) {
                            //跳转到微信端的界面
                            return "mobile/index";
                        } else {
                            //默认跳转到pc端界面
                            return "pc/index";
                        }
                    }

                }
            } catch (Exception e) {
                //报错直接跳转到登录界面
                if (type.equals("2")) {
                    //跳转到微信端的界面
                    return "mobile/index";
                } else {
                    //默认跳转到pc端界面
                    return "pc/index";
                }
            }
        }
        //验证不通过,跳转到登录界面,type不传默认跳转到pc端登录
        return "/pc/index";
    }

 

posted @ 2019-05-14 14:05  zexzhang  阅读(3379)  评论(0编辑  收藏  举报