JWT实作(二)(Day6)

要利用帐号密码验证使用者,首先我们必须要有使用者(废话?
在 stockapi资料库里面新增一个表单(user)

CREATE TABLE users (
ID INT NOT NULL AUTO_INCREMENT COMMENT '使用者ID',
ACCOUNT VARCHAR(50) NOT NULL DEFAULT '0' COMMENT '使用者帐号',
NAME VARCHAR(50) NOT NULL DEFAULT '0' COMMENT '使用者姓名',
PASSWORD VARCHAR(60) NOT NULL DEFAULT '0' COMMENT '使用者密码(加密过)',
PRIMARY KEY (ID)
)
COMMENT='使用者'
COLLATE='utf8_general_ci';

在pom.xml再引入两个套件,使我们可以与资料库进行沟通

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

接着我们必须要创建使用者

1.创建与资料库沟通的类别
新建一个 package - repository
新增一个 Class - UserRepository

package com.stockAPI.repository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import com.stockAPI.model.User;

@Repository
public class UserRepository {

	@Autowired
	NamedParameterJdbcTemplate namedParameterJdbcTemplate;
	
	public Integer add(User user) {
		KeyHolder keyHolder = new GeneratedKeyHolder();
		SqlParameterSource sqlParameterSource=new BeanPropertySqlParameterSource(user);
		String sql = " INSERT INTO stockapi.users ( ACCOUNT, NAME, PASSWORD ) "
				   + " VALUE ( :account, :name, :password ) " ;
		namedParameterJdbcTemplate.update(sql, sqlParameterSource,keyHolder);
		return keyHolder.getKey().intValue();
	}

这边我们用NameParameterJdbcTemplate与JdbcTemplate的差异在於,他可以 :参数名称
而不是利用 ? 号这样的代位符号,好处是可以避免因为参数塞入的顺序错误,而导致SQL
语法报错。
NameParameterJdbcTemplate实际上也是透过重新包装JdbcTemplate产生的模板,因此他们的底层原理是一样的。

2.实作StockUserServcie的业务逻辑
新建一个 package - service
新增一个Class - StockUserServcie 继承 UserDetailServcie (之後登入会用到)

package com.stockAPI.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.stockAPI.model.User;
import com.stockAPI.repository.UserRepository;


@Service
public class StockUserService implements UserDetailsService {
	
	
	@Autowired
	UserRepository userRepository;
	
	//载入套件的加密器
	@Autowired
	BCryptPasswordEncoder bCryptPasswordEncoder;

	//目前还没要用到,先不实作
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		return null;
		
	}
	
	public Integer addUser(User user) {
		user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
		Integer user_id = userRepository.add(user);
		return user_id;
	}
}

3.修改security设定并注册加密器

@Override
    protected void configure(HttpSecurity http) throws Exception {
    	http
    		.authorizeRequests()
    		.antMatchers("/user/testBlock").authenticated()
    		.antMatchers("/user/testUnblock").permitAll()
    		.antMatchers("/user/create").permitAll()
    		.and()
    		.csrf().disable(); 
        
    }
    
    //加密器注入容器
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

csrf().disable(); 必须启用,不然外部网域无法请求,这与我们接下来要用postman测试有关

4.新增API回传物件

package com.stockAPI.model;

import java.util.Map;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class APIReturnObject {
	
	private String message;
	
	private Map<String, Object> data;

}

5.新增controller路径设置

@PostMapping("create")
public APIReturnObject create(@RequestBody User user) {
APIReturnObject result = new APIReturnObject();
Map<String, Object> data = new HashMap<String, Object>();
Integer user_id = stockUserService.addUser(user);
data.put("user_id", user_id);
result.setMessage("用户资料新增成功");
result.setData(data);
return result;
}

我们目前预设 如果用户资料新增成功会回传 用户ID

再来是注册postman
https://www.notion.so/JWT-daf2d86fbaa44554a10675f13db40b31#6730f3d3efdb4de8bded483ed4680288
记得安装postman Desktop版本

接着
https://ithelp.ithome.com.tw/upload/images/20210921/20138857zcG2U5cllZ.png

设定好 网址、方法、参数 按 Send

就可以看到
https://ithelp.ithome.com.tw/upload/images/20210921/20138857UCe42vYI4S.png

请注意一件事,因为我们Controller接受参数的注解使用的是 @RequestBody 因此参数
不要塞错塞到Params,这样Controller会因为接受不到参数而报错喔!!

这时候你一定会有疑问,会员新增的权限是谁都可以吗? 我们要怎麽判断权限?
这些留待我们明天继续说明~~


<<:  我们的基因体时代-AI, Data和生物资讯 Day21- 基因注释资料在Bioconductor中物件:IRanges和GenomicRanges

>>:  Day 06 JavaScript/Rails AJAX

RWD
杂谈    

我如何锻链解决问题的能力——全端开发者内功 III

from Steps to develop problem-solving skills 我认为没...

[Day 30] 使用ChromeDriver来做单元测试(三)

同时开启多个浏览器 有时候可能需要多个浏览器来进行测试, 譬如说用多个浏览器来测试WebSocket...

android studio 30天学习笔记-day 8-基本介绍rxjava2

RxJava2是一套处理非同步(asynchronous)事件的library,这个library是...

[CSS] Flex/Grid Layout Modules, part 1

万事起头难,只要不起头,就一点都不难了。 在这个充满着 CSS Frameworks 的年代,人人...

世界上最快乐的人 (1) 实修方法摘录

这两天去上 SIY 的工作坊,为了应景,改变一下主题。手边刚好有明就仁波切的《世界上最快乐的人》,摘...