---
# System prepended metadata

title: '**登入頁面**'
tags: [java]

---

{%hackmd @themes/orangeheart %}

# **登入頁面**
![](https://i.imgur.com/FLr0YNO.png)
<font color="3E54AC"> **使用到的技術**
:computer:	Spring Security
:computer:	Spring Mail</font>

首頁主要有三個功能實現
1. 用戶登入
2. 快速註冊
3. 忘記密碼(密碼重置)

## 用戶登入
>這邊使用==Spring Security==進行登入驗證

:point_right:流程如下	:point_left:
1. Client發送請求
2. Filter攔截請求，解析請求是否包含JWT(token)
    * 包含則將解析後的JWT放入SecurityContext
    * 不包含直接放行進行下一步驗證
3. 訪問UserController
4. 透過AuthenticationManager進行身份驗證
5. 最後將UserId、Username、權限封裝成JWT(token)響應給Client 
![](https://i.imgur.com/850lkju.png)

>用戶登入以後透過:point_down:開啟權限驗證
>@EnableGlobalMethodSecurity(prePostEnabled = true)
>根據每個用戶身份的不同能使用的功能就不同

透過@PreAuthorize("hasRole('admin')")設定訪問權限
該方法只有權限為==admin==的用戶才能訪問
```java
    @PostMapping("/insert")
    @ApiOperation("新增商品")
    @ApiOperationSupport(order = 100)
    @PreAuthorize("hasRole('admin')")
    public JsonResult insert(@RequestBody ProductAddNewDTO productAddNewDTO){
        log.debug("開始新增商品");
        productService.insert(productAddNewDTO);
        return JsonResult.ok();
    }
```


## 用戶註冊
![](https://i.imgur.com/AP0WOaR.png)
>只使用用戶名稱與用戶密碼進行快速註冊，並且使用==PasswordEncoder==對密碼進行加密
```java
    @Override
    public void reg(UserRegDTO userRegDTO) {
        log.debug("開始service.reg");
        /*使用username查詢是否重複註冊*/
        int count = userMapper.countByUsername(userRegDTO.getUsername());
        if(count > 0){
            throw new ServiceException(ServiceCode.ERR_BAD_REQUEST,"用戶名稱已被註冊!");
        }

        /*準備要寫入資料庫的資料*/
        User user = new User();
        user.setUsername(userRegDTO.getUsername());
        //密碼加密
        String encode = passwordEncoder.encode(userRegDTO.getPassword());
        user.setPassword(encode);

        /*補充用戶資料*/
        //預設用戶暱稱為註冊帳號
        user.setNickname(userRegDTO.getUsername());

        //資料寫入資料庫
        int rows = userMapper.insert(user);
        if(rows != 1){
            throw new ServiceException(ServiceCode.ERR_INSERT,"伺服器忙碌中，請稍候再試!");
        }
        log.debug("註冊完成");
    }
```
## 忘記密碼(密碼重置)
![](https://i.imgur.com/1lAPSsu.png)
>用戶可以輸入用戶名稱進行密碼重置，並通過==Spring Mail==發送重置過的密碼到用戶的信箱

:point_right:流程如下	:point_left:
1. 驗證該用戶名是否存在，不存在則拋異常
2. 透過用戶名獲取信箱
3. 生成隨機密碼並使用==PasswordEncoder==加密
4. 更新資料庫內的用戶密碼
5. 透過==Spring Mail==發送重置過的密碼

###### tags: `java`