07 登录接口开发

登录接口开发

登录的逻辑其实很简答,只需要接受账号密码,然后把用户的id生成jwt,返回给前段,为了后续的jwt的延期,所以我们把jwt放在header上。具体代码如下:

  • com.gychen.controller.AccountController
@RestController
public class AccountController {
    @Autowired
    JwtUtils jwtUtils;
    @Autowired
    UserService userService;
    /**
     * 默认账号密码:gychen / 111111
     *
     */
    @CrossOrigin
    @PostMapping("/login")
    public Result login(@Validated @RequestBody LoginDto loginDto, HttpServletResponse response) {
        User user = userService.getOne(new QueryWrapper<User>().eq("username", loginDto.getUsername()));
        Assert.notNull(user, "用户不存在");
        if(!user.getPassword().equals(SecureUtil.md5(loginDto.getPassword()))) {
            return Result.fail("密码错误!");
        }
        String jwt = jwtUtils.generateToken(user.getId());
        response.setHeader("Authorization", jwt);
        response.setHeader("Access-Control-Expose-Headers", "Authorization");
        // 用户可以另一个接口
        return Result.succ(MapUtil.builder()
                .put("id", user.getId())
                .put("username", user.getUsername())
                .put("avatar", user.getAvatar())
                .put("email", user.getEmail())
                .map()
        );
    }
    
    // 退出
    @GetMapping("/logout")
    @RequiresAuthentication
    public Result logout() {
        SecurityUtils.getSubject().logout();
        return Result.succ(null);
    }
}

  • 在postman软件里写接口请求测试

请求类型为POST,URL为http://localhost:8081/login,依次选择Body->raw->JSON


{
    "_comment":"postman清求数据",
    "username":"gychen",
    "password":"111111"
}

{
    "_comment":"服务器返回数据",
    "code": "0",
    "msg": "操作成功",
    "data": {
        "id": 1,
        "avatar": "https://image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/5a9f48118166308daba8b6da7e466aab.jpg",
        "email": null,
        "username": "gychen"
    }
}

博客接口开发

我们的骨架已经完成,接下来,我们就可以添加我们的业务接口了,下面我以一个简单的博客列表、博客详情页为例子开发:

  • com.gychen.controller.BlogController
package com.gychen.controller;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gychen.common.lang.Result;
import com.gychen.entity.Blog;
import com.gychen.service.BlogService;
import com.gychen.util.ShiroUtil;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author gychen
 * @since 2020-07-28
 */


@RestController
public class BlogController {
    @Autowired
    BlogService blogService;
    @GetMapping("/blogs")
    public Result blogs(Integer currentPage) {
        if(currentPage == null || currentPage < 1) currentPage = 1;
        Page page = new Page(currentPage, 5);
        IPage pageData = blogService.page(page, new QueryWrapper<Blog>().orderByDesc("created"));
        return Result.succ(pageData);
    }
    @GetMapping("/blog/{id}")
    public Result detail(@PathVariable(name = "id") Long id) {
        Blog blog = blogService.getById(id);
        Assert.notNull(blog, "该博客已删除!");
        return Result.succ(blog);
    }

    @RequiresAuthentication    // 此接口必须要通过登录认证才能访问
    @PostMapping("/blog/edit")
    public Result edit(@Validated @RequestBody Blog blog) {
        System.out.println(blog.toString());
        Blog temp = null;
        if(blog.getId() != null) {
            // 在数据库中查找传入id的博客存不存在
            temp = blogService.getById(blog.getId());
            // Assert.isTrue(temp.getUserId().longValue() == ShiroUtil.getProfile().getId().longValue(), "没有权限编辑");
            Assert.isTrue(temp.getUserId().equals(ShiroUtil.getProfile().getId()), "没有权限编辑");
        } else {
            temp = new Blog();
            temp.setUserId(ShiroUtil.getProfile().getId());
            temp.setCreated(LocalDateTime.now());
            temp.setStatus(0);
        }
        // 把blog复制到temp并忽略id、userId、created、status
        BeanUtil.copyProperties(blog, temp, "id", "userId", "created", "status");
        blogService.saveOrUpdate(temp);
        return Result.succ(null);
    }
}


  • 在postman软件里写接口请求测试
  1. 先进行登录请求,登陆成功后在返回数据的请求头Headers里找到Authorization的value,复制value值

  2. 新建一个请求,请求类型为POST,URL为http://localhost:8081/blog/edit,在Headers里新建key:Authorization,value:复制的value值,依次选择Body->raw->JSON

  3. 测试代码

    • {
       "title":"测试标题3333333333",
       "description":"description333333333",
       "content":"content33333333333"
      }
      
    • {
        "title":"测试标题3333333333",
        "description":"description333333333"
      }
      
    • {
       "id":11,
       "title":"测试标题3333333333",
       "description":"description333333333",
       "content":"content33333333333"
      }
      
    • {
       "id":11,
       "title":"修改测试标题3333333333",
       "description":"description333333333",
       "content":"content1111111"
      }
      
  4. 暂时在这里出现了登录验证的问题,待解决

  5. 找了大概一个小时,在JwtFilter的onAcessDenied方法里发现发起请求时,后端根本在Header请求头里找不到jwt,后来发现原来是在postman里把token放Params里传给后端了。

  6. 测试结果

    • {
          "code": "0",
          "msg": "操作成功",
          "data": null
      }
      
    • {
          "code": "-1",
          "msg": "内容不能为空",
          "data": null
      }
      
    • {
          "code": "0",
          "msg": "操作成功",
          "data": null
      }
      
    • {
          "code": "0",
          "msg": "操作成功",
          "data": null
      }
      

注意@RequiresAuthentication说明需要登录之后才能访问的接口,其他需要权限的接口可以添加shiro的相关注解。 接口比较简单,我们就不多说了,基本增删改查而已。注意的是edit方法是需要登录才能操作的受限资源。

原文地址:https://www.cnblogs.com/nuister/p/13495385.html