《web应用技术》第十次课后作业

1、编写登录页面,让自己的页面有权限管理功能。

基础登录功能:

重新创建一个LoginController:

@Slf4j
@RestController
public class LoginController {

    @Autowired
    private ReaderService readerService;

    @PostMapping("/login")
    public Result login(@RequestBody Reader reader){
        //将json格式的数据封装到实体类中,添加注解@RequestBody
        log.info("员工登录:{}",reader);
        Reader r = readerService.login(reader);
        return r != null? Result.success():Result.error("用户名或密码错误!");
        //如果r不为空,则返回success,否则返回error
    }
}

ReaderService:

public interface ReaderService {
    //员工登录操作
    public Reader login(Reader reader);
}

ReaderServiceImpl:

@Service
public class ReaderServiceImpl implements ReaderService {

    @Autowired
    private ReaderMapper readerMapper;

    @Override
    public Reader login(Reader reader) {
        return readerMapper.getByUsernameAndPassword(reader);
    }
}

ReaderMapper:

@Mapper
public interface ReaderMapper {

    @Select("select * from reader where username = #{username} and password = #{password}")
    public Reader getByUsernameAndPassword(Reader reader);
}

postman测试:

登录校验:

浏览器与服务器之间进行交互是经过HTTP协议的,http协议又是无状态的,每一次请求都是独立的,不会携带上一次请求的数据。

服务端要想判断用户是否已经登录,就要在用户登录成功之后存储一个登录标记。统一拦截技术来拦截浏览器发送过来的所有的请求,拦截到请求后就可以对这个请求进行校验是否登录,获取之前所存入的登录标记,获取到则说明该用户已经登录,否则前端跳转到登录页面。

会话技术:

会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。

会话跟踪:一种维护浏览器状态的方法,服务器只需要识别多此请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。

客户端会话跟踪技术:cookie

浏览器第一次发起请求来请求服务器的时候设置一个cookie存储相关的数据信息,服务器会自动的将cookie响应给浏览器,浏览器将返回cookie的值自动的存储在本地,后续的每一次请求浏览器会自动的将本地存储的cookie又携带到服务端,服务端判断该cookie之前是否存在,若不存在说明该客户端之前没有访问登录接口的,若存在则已登录。

响应头:(set-Cookie:name=value)

请求头:(Cookie:name=value)

优点:HTTP协议中支持的技术

缺点:移动端APP无法使用Cookie,不安全(用户可以自己禁用Cookie),不能跨域。

服务端会话跟踪技术:session

浏览器在第一次请求服务器时,服务器创建会话对象session,每一个session都有一个id,服务器端给浏览器响应数据时会将id通过Cookie响应给浏览器,(Set-Cookie:JSESSION=1),浏览器接收到响应数据后自动将Cookie存储在浏览器本地,在后续的每一次请求都会将Cookie的数据获取出来并且带到服务端,服务器拿到session的id会从众多的session中找到当前请求的会话对象session。

优点:存储在服务端,安全

缺点:服务器集群环境下无法直接使用Session,Cookie的缺点

令牌技术

如果登录成功,则生产一个令牌,为该用户的合法身份凭证,响应数据时将令牌直接响应给前端,前端接收到后将令牌存储起来,之后的每一次请求都要将令牌携带到服务端,校验令牌的有效性,有效则已经执行了登录操作,无效说明并未登录,共享的数据也可以储存在令牌中。

优点:支持pc端、移动端,解决集群环境下的认证问题,减轻服务器端存储的压力。

缺点:需要自己实现。

JWT令牌:

JSON Web Token 一种简洁的,自包含的格式,用于在通信双方以json数据格式安全的传输信息。

组成:header(头)、payload(有效载荷)、signature(签名)

场景:登录认证

登录成功后,生成令牌;后续每个请求,都要携带JWT令牌,系统在每次出来请求之前,先校验令牌,通过后,再处理。

JWT-生成和校验

pom文件中引入依赖后编写测试类:

在官网解析后:

jwt-校验:

controller中实现:

@Slf4j
@RestController
public class LoginController {

    @Autowired
    private ReaderService readerService;

    @PostMapping("/login")
    public Result login(@RequestBody Reader reader){
        //将json格式的数据封装到实体类中,添加注解@RequestBody
        log.info("员工登录:{}",reader);
        Reader r = readerService.login(reader);

        //登录成功,生成令牌,下发令牌
        if(r != null){
            Map<String,Object> claims = new HashMap<>();
            claims.put("id",r.getId());
            claims.put("username",r.getUsername());
            String jwt = JwtUtils.generateJwt(claims);
            return Result.success(jwt);
        }

        //登陆失败,返回错误信息
        return Result.error("用户名或密码错误!");
    }

}

postman测试:用户名密码正确,成功下发jwt令牌

编写页面:读者的账号密码正确,登录信息写入session中,则每个页面课可以通过读取session信息判断是否为有权限。如果没有写入session,或者session信息被清除了,则通过判断确定没有权限访问。

实现:

当输入用户名和密码时:

跳转到index1成功登录:

且在控制台输出:

跳转到index2:

点击退出登录后:

当输入错误的密码时:

且在控制台输出:

代码:

index1.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>必须成功登录才能访问</title>
    <link rel="stylesheet" href="js/element.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/vue.js"></script>
    <script src="js/element.js"></script>
    <script src="js/axios-0.18.0.js"></script>

</head>
<body>
<div id="app">
    <div v-if="tableData.code==1">
        <h1 align="center">页面1--成功</h1>
        <a href="index2.html">页面2</a>
        <a href="logout">退出登录</a>

        <h2 align="center">我天你竟然登录成功了,下面是登录信息展示~</h2>

            <table border="1" align="center" width="800px">
            <tr>
                <th>code</th>
                <th>msg</th>
                <th>data</th>
            </tr>
            <tr>
                <td>{{tableData.code}}</td>
                <td>{{tableData.msg}}</td>
                <td>{{tableData.data}}null</td>
            </tr>
        </table>
    </div>
        <div v-else-if="tableData.code==0">
            code={{tableData.code}}没有权限访问!sorry啦!
        </div>
</div>

<script>
    new Vue({
        el:"#app",
        data:{
            tableData: {
                code:""  ,
                msg:""  ,
                data:""
            }
        },

        mounted() {

            var url = `/index1`
            axios.get(url)
                .then(response => {
                    this.tableData = response.data;
                    console.log(this.tableData);
                })
                .catch(error=>{
                    console.error(error);
                })
        }

    })

</script>

</body>
</html>

index2.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>必须成功登录以后才能访问</title>
    <link rel="stylesheet" href="js/element.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/vue.js"></script>
    <script src="js/element.js"></script>
    <script src="js/axios-0.18.0.js"></script>
</head>
<body>

<div id="app">
  <div v-if="tableData.code==1">
    <h1 align="center">页面2--成功</h1>
    <a href="index1.html">页面1</a>
    <a href="logout">退出登录</a>
    <h2 align="center">我天index2你竟然也登录成功了,下面是登录信息展示~</h2>

    <table border="1" align="center" width="800px">
      <tr>
        <th>code</th>
        <th>msg</th>
        <th>data</th>
      </tr>
      <tr>
        <td>{{tableData.code}}</td>
        <td>{{tableData.msg}}</td>
        <td>{{tableData.data}}null</td>
      </tr>
    </table>
  </div>

  <div v-else-if="tableData.code==0">
    {{tableData.code}}没有权限访问!
  </div>

</div>

<script>
  new Vue({
    el:"#app",
    data:{
      tableData: {
        code:""  ,
        msg:""  ,
        data:""
      }
    },

    mounted() {

      var url = `/index2`
      axios.get(url)
              .then(response => {
                //this.tableData = response.data;
                this.tableData = response.data;
                console.log(this.tableData);
              })
              .catch(error=>{
                console.error(error);
              })
    }

  })

</script>

</body>
</html>

ReaderSessionController:

package com.example.librarymasterlendlist.Controller;

import com.example.librarymasterlendlist.Pojo.Reader;
import com.example.librarymasterlendlist.Pojo.Result;
import com.example.librarymasterlendlist.Service.ReaderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

@RestController
public class LoginSessionController {
    @Autowired
    private ReaderService readerService;

    @PostMapping("/login_session")
    public Result login(HttpServletRequest request, @RequestBody Reader readers){
        Reader r = readerService.login(readers);
        if (r != null){
            request.getSession().setAttribute("reader",readers.getUsername());
            String reader = (String)request.getSession().getAttribute("reader");
            System.out.println("查询不为空" + reader);
            return Result.success();
        }
        else {
            String reader = (String)request.getSession().getAttribute("reader");
            System.out.println("查询为空" + reader);
            return Result.error("用户名或密码错误");
        }
    }

    @GetMapping("/logout")
    public Result logout(HttpServletRequest request){
        //清理Session中保存的当前登录员工的id
        request.getSession().removeAttribute("reader");
        return Result.success("退出成功");

    }

    @GetMapping("/index1")
    public Result index1(HttpServletRequest request) {
        String reader = (String) request.getSession().getAttribute("reader");
        if (reader != null) {
            return Result.success();
        } else {
            return Result.error("无权限");
        }
    }

        @GetMapping("/index2")
        public Result index2(HttpServletRequest request) {
            String reader = (String) request.getSession().getAttribute("reader");
            if (reader != null) {
                return Result.success();
            } else {
                return Result.error("无权限");
        }

    }

}

ReaderService、ReaderServiceImpl、ReaderMappert同上。

2、将自己的项目改造为基于vue-cli脚手架的项目,页面有导航,学会使用router

index.js:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    redirect: '/lend'
  },
  {
    path: '/reader',
    name: 'reader',
    component: () => import( '../views/library_lend/ReaderView.vue')
  },
  {
    path: '/lend',
    name: 'lend',

    component: () => import( '../views/library_lend/LendView.vue')
  }
]

const router = new VueRouter({
  routes
})

export default router

添加<router-link to="/xxx"></router-link>标签

3、开始尝试用markdown格式在vs code中写接口文档。(部分)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值