改造vue-element-admin 的登录功能,变成从后台数据库中验证登录

首先了解登录时前段需要什么样的数据

要知道vue-element-admin 这个后台开发模板是集成非常多我们日常开发网站的基本功能。所以我们在改造登录功能的时候首先要明白vue-element-admin 需要后端提供什么样的数据才能完成后端的校验完成登录。

如下图:

element ui组件登录表单_mysql

从图中可以看到登录的时候必须后端会根据你的请求给你的返回一个状态码:20000 token令牌 success 成功的信息。再接着我们查看vue-element-admin 的源码 mock 假数据这一部分看看 花裤衩大佬是怎么给数据进行校验的。

如下图:

element ui组件登录表单_element ui组件登录表单_02

上面这张图是我改造过的,我就是把前面的通过获取假数据那个请求删掉了改成了向后端请求数据。但是该这边是不够的还需要改另一个地方。.env.development 这个开发时候的文件。把框起来的地方改成自己后端的地址即可这样的话他就不会走mock提供假数据的路劲了,会直接访问你后端提供的接口 http://localhost:8070/user/login,如下图

element ui组件登录表单_mysql_03

到这一步的话就已经完成前端的接口改造部分,那么现在就是要写后端去返回前端所需要的那几个数据了

改造后端

后端我采用的是springboot+jwt 当然SSM也是可以的!!!
1、首先我们一样的先在数据库准备好一张提供登陆信息的表,含有 username password roles avatar 大概就是这几个字段可以自行添加其他的字段,登录只要用到这几个就行。目前这个阶段我们就只要用 username password

2、接着我们要进行对后端的接口的编写 conctroller层 提供/user/login /user/logout /user/getInfo 这三个接口。
上代码:

/**
 * @author: phil
 * @ProjectName: vue-admin-element-demo-01
 * @Date: 2021/6/15
 */
@RestController
public class UserController {
    @Autowired
    private UserService userService;


    @PostMapping("/user/logout")
    public ResultResponse logout(@RequestHeader("X-Token") String token){
        ResultResponse res = new ResultResponse();
        // 验证token的合法和有效性
        String tokenValue = JwtUtil.verity(token);// success:zhangsan1
        // 获取token中的用户名
        String username = tokenValue.replaceFirst(JwtUtil.TOKEN_SUCCESS, "");
        // 移除session中的登录标记(或者redis中的登录标记)
        res.setMessage("logout success");
        res.setData("logout success");
        res.setCode(Constants.STATUS_OK);

        return res;
    }



    @GetMapping("/user/info")
    public ResultResponse info(@RequestParam("token") String token){
        ResultResponse res = new ResultResponse();

        // 验证token的合法和有效性
        String tokenValue = JwtUtil.verity(token);// success:zhangsan1
        if(tokenValue != null && tokenValue.startsWith(JwtUtil.TOKEN_SUCCESS)) {
            // 如果ok-》返回需要的用户信息
            // zhangsan1
            String username = tokenValue.replaceFirst(JwtUtil.TOKEN_SUCCESS, "");

            //下面的应该是从数据库中拿到的,现在写死了
//            VoUser user = this.userService.searchUserByUserName(username);
            VoUserInfo info = new VoUserInfo();
            info.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
            info.setIntroduction("测试用户");
            info.setName(username);

            //给用户设定角色
            List<String> roles = Arrays.asList("tmnl");
            info.setRoles(roles);

            res.setData(info);
            res.setMessage(Constants.MESSAGE_OK);
            res.setCode(Constants.STATUS_OK);
        }else {
            // 否则:500
            res.setCode(Constants.STATUS_FAIL);
            res.setMessage(Constants.MESSAGE_FAIL);
        }

        return res;
    }

    @PostMapping("/user/login")
    public ResultResponse login(@RequestBody VoUser user){
        ResultResponse res = new ResultResponse();
        try {
            //调用UserService完成username和password的验证
            VoUser u = this.userService.verify(user);
            //根据验证结果,组成响应对象返回
            if (u!=null){
             //创建一个token数据,封装到res对象中
                String token = JwtUtil.sign(user.getUsername(), "-1");
                res.setCode(Constants.STATUS_OK);
                res.setMessage(Constants.MESSAGE_OK);
                res.setData(new VoToken(token));
            }else {
                res.setCode(Constants.STATUS_FAIL);
                res.setMessage(Constants.MESSAGE_FAIL+"用户名和密码不匹配");
                res.setData("fail");
            }
        } catch (Exception e) {
            res.setCode(Constants.STATUS_FAIL);
            res.setMessage(Constants.MESSAGE_FAIL+"用户名和密码不匹配");
            res.setData("fail");
            e.printStackTrace();
        }
        return res;
    }


}

还有必须写完下面几个文件才能用:(这里不再补充,因为很简单)

element ui组件登录表单_element ui组件登录表单_04


element ui组件登录表单_vue.js_05


element ui组件登录表单_jwt_06


element ui组件登录表单_spring_07

3、接下来就是关键的东西咯!返回一个token给前端

3.1 写一个JwtUtil 的工具类

public class JwtUtil {
    public static final String TOKEN_LOGIN_NAME = "loginName";
    public static final String TOKEN_LOGIN_ID = "userId";
    public static final String TOKEN_SUCCESS = "success:";
    public static final String TOKEN_FAIL = "fail:";
    /**
     * 过期时间为一天
     * TODO 正式上线更换为15分钟
     */
    private static final long EXPIRE_TIME = 24*60*60*1000;

    /**
     * token私钥
     */
    private static final String TOKEN_SECRET = "joijsdfjlsjfljfljl5135313135";

    /**
     * 生成签名,15分钟后过期
     * @param username
     * @param userId
     * @return
     */
    public static String sign(String username,String userId){
        //过期时间
        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
        //私钥及加密算法
        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
        //设置头信息
        HashMap<String, Object> header = new HashMap<>(2);
        header.put("typ", "JWT");
        header.put("alg", "HS256");
        //附带username和userID生成签名
        return JWT.create().withHeader(header).withClaim(TOKEN_LOGIN_NAME,username)
                .withClaim(TOKEN_LOGIN_ID,userId).withExpiresAt(date).sign(algorithm);
    }


    public static String verity(String token){
        String result = TOKEN_SUCCESS;
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            result += jwt.getClaims().get(TOKEN_LOGIN_NAME).asString();
            return result; // success:username
        } catch (IllegalArgumentException e) {
            return TOKEN_FAIL+e.getMessage();
        } catch (JWTVerificationException e) {
            return TOKEN_FAIL+e.getMessage();
        }catch (Exception e){
            return TOKEN_FAIL+e.getMessage();
        }

    }
}

3.2 、补充完这个工具类所需要的实体类

element ui组件登录表单_jwt_08

@Data
@NoArgsConstructor
@AllArgsConstructor
public class VoToken {
    private String token;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class VoUserInfo {
    private List<String> roles;
    private String introduction;
    private String avatar;
    private String name;
}

最后还需要一个 返回给前端的实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class ResultResponse {
    private int code;
    private String message;
    private Object data;
}

最后配置到这边后端的所有改造代码也就完成了

结果

element ui组件登录表单_element ui组件登录表单_09


最后希望这篇写的不够好的文章能够给你带来一点帮助!!!