07 登入介面開發
阿新 • • 發佈:2020-08-13
登入介面開發
登入的邏輯其實很簡答,只需要接受賬號密碼,然後把使用者的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軟體裡寫介面請求測試
-
先進行登入請求,登陸成功後在返回資料的請求頭Headers裡找到Authorization的value,複製value值
-
新建一個請求,請求型別為POST,URL為http://localhost:8081/blog/edit,在Headers裡新建key:Authorization,value:複製的value值,依次選擇Body->raw->JSON
-
測試程式碼
-
{ "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" }
-
-
暫時在這裡出現了登入驗證的問題,待解決
-
找了大概一個小時,在JwtFilter的onAcessDenied方法裡發現發起請求時,後端根本在Header請求頭裡找不到jwt,後來發現原來是在postman裡把token放Params裡傳給後端了。
-
測試結果
-
{ "code": "0", "msg": "操作成功", "data": null }
-
{ "code": "-1", "msg": "內容不能為空", "data": null }
-
{ "code": "0", "msg": "操作成功", "data": null }
-
{ "code": "0", "msg": "操作成功", "data": null }
-
注意@RequiresAuthentication說明需要登入之後才能訪問的介面,其他需要許可權的介面可以新增shiro的相關注解。 介面比較簡單,我們就不多說了,基本增刪改查而已。注意的是edit方法是需要登入才能操作的受限資源。