回顾前一天讲的MVC,下达request到Controller後,由Service去执行资料的 增/删/改/查,最後再呈现在View上
在以前,我们会新增一支class继承 HttpServlet,然後实作doGet、doPost,
除了要写一堆if判断request并做出对应的操作、还要负责页面的转导等等工作
现在有了spring boot,而且做的是前後端分离,
只要在Controller做出能让前端好call的api就行了,做起来也相对简单明了
今天就来做User的登入api
这边我想仿作银行的三层式帐密(ID+User+Password),
在这之前,我有在Service再补加一个verifyUser
的方法,是用来验证登入帐号密码的,
其实就只是简单的检查字串,
实际上银行的帐号密码验证是不会这麽阳春的,
而且传入Server的值会在client端就先加密,
确保封包不会被侧录(end-to-end encryption),
总之很安全,有空的话就再来试着实作简单版的ETOEE
public String verifyUser(String email,String userAcct , String userPasswd){
/*
0000 login success
0001 wrong email
0002 wrong useracct
0003 wrong passwd
0004 acct locked
9999 unknown error
*/
Optional<User> user=userRepo.findUserByEmail(email);
String result="9999";
if(user.isPresent()){
if(user.get().getUserAccount().equals(userAcct)){
if(user.get().getUserPassword().equals(userPasswd)){
result="0000";
}else{
result="0003";
}
}else{
result="0002";
}
}else{
result="0001";
}
return result;
}
本来想再加个密码错5次就锁定帐号跟检查帐号状态,之後有时间再补充好了
接着来到controller,今天要实作登入的api
@RestController
@RequestMapping("api/user")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping("/login")
public ResponseEntity<String> userLogin(@RequestBody Map<String,String> map){
String email= map.get("email");
String userAccount= map.get("userAccount");
String userPassword= map.get("userPassword");
String result="null data";
if(StringUtils.isBlank(email)||StringUtils.isBlank(userAccount)||StringUtils.isBlank(userPassword)){
return ResponseEntity.ok(result);
}else{
result=userService.verifyUser(email, userAccount, userPassword);
return ResponseEntity.ok(result);
}
}
}
在这边我用了5个annotation:
@RestController
用来告诉Spring这是一个RestController,
@RestController
跟@Controller
的区别是
@RestController
下的方法return的值会直接被预设为Response body回传
@RestController
也等於是@Controller
+@ResponseBody
@RestController
适用於api这样直接回传值的需求
@Controller
则是适合用在jsp、thymeleaf这种Server同时也负责页面渲染的情况
接着,当Spring知道这是一个Controller後就会去检查有没有@RequestMapping
并将这个Controller绑在相对的url上,像我设定的是"api/user",
因此会对应到的url是 localhost:8080/api/user
@RequiredArgsConstructor
跟昨天在Service的用法一样是用来实体化物件用的就不赘述
@PostMapping
应该很好理解
就是对应浏览器的HTTP method的实作
相关的有:
@GetMapping
@PostMapping
@DeleteMapping
@PutMapping
@PatchMapping
我在这边决定以POST方法来实做登入功能,
@PostMapping("/login")对应到 localhost:8080/api/user/login
@PostMapping("/login")
public ResponseEntity<String> userLogin(@RequestBody HashMap<String,String> map){
String email= map.get("email");
String userAccount= map.get("userAccount");
String userPassword= map.get("userPassword");
String result="请输入帐号密码!";
if(StringUtils.isBlank(email)||StringUtils.isBlank(userAccount)||StringUtils.isBlank(userPassword)){
return ResponseEntity.ok(result);
}else{
result=userService.verifyUser(email, userAccount, userPassword);
return ResponseEntity.ok(result);
}
}
@RequestBody
会接收Post发送过来的request Body,我选择以HashMap来储存,
(其实应该要用User这个Object来存较好,
用HashMap的话除了无法对传入的值做最低限度的限制,也降低程序码的可读性)
Spring会将requestBody转为Map的形式传入
虽然到时候在前端会检查,不过我在这边还是有做一下null检核,
org.apache.commons.lang3.StringUtils,好用!
要记得在pom.xml加个dependency
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
本来在想登入成功跟失败的Response Code是不是要有区别比较好,不过还没想到前端到时候会怎麽做
就决定先全部都回200,也就是ok
在测试api时发现post方法一直回传"status":403,"error":"Forbidden"
查了一下发现原来是因为Spring Security的预设设定有CSRF的保护
会阻挡没带CSRF token的POST、PATCH、PUT、DELETE等http method
为求测试方便,先把这个功能关闭,顺便也关掉Spring Security的登入页
建立一个WebSecurityConfig.java,
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().permitAll() //让所有页面都不用登入
.and().csrf().disable(); //关掉csrf保护
}
}
接着再测就成功把post送到server了
回0000,表示帐号密码正确
今天就先这样吧!
>>: 每个人都该学的30个Python技巧|技巧 21:set的处理方法(字幕、衬乐、练习)
今天也要来讲解组件的基础,基础打好未来学习新的东西才不会搞得东倒西歪,虽然今天已经27天了o(^▽^...
「欢迎来到 XX 的大家庭,希望大家把团队当作家人,一起成长……」 这是在某间公司报到时,HR 对我...
学习进度 Android Studio View(View、Image view、Text view...
好的,前一篇讲到了flow可以完全取代liveData,其实错!! 直接从结论开始讲,flow并不支...
我们昨天建立完Project後,我们再仔细深入研究的话,会发现第二层的Test里面还有其他额外的四个...