关于java:北大博士带你解密怎么用Java轻松实现鉴权服务小白太简单了

42次阅读

共计 10655 个字符,预计需要花费 27 分钟才能阅读完成。

今日分享开始啦,请大家多多指教~

现今大部分零碎都会有本人的鉴权服务,它是用户与零碎交互的第一步,零碎须要一系列步骤明确你是谁,你能够做哪些事,明确了这些之后它能力更好的服务于你。

一、何为鉴权服务

鉴权(authentication)是指验证用户是否领有拜访零碎的权力。

鉴权包含两个方面:

  • 用户鉴权,网络对用户进行鉴权,避免非法用户占用网络资源。
  • 网络鉴权,用户对网络进行鉴权,避免用户接入了非法的网络,被骗取要害信息。

而咱们这里的鉴权次要指用户鉴权,即如何确认“你是你”。最简略的体现便是平时用的用户登录登出。

二、利用 servlet+jdbc 实现简略的用户登录程序

1. 明确思路

首先,咱们要认真思考一下咱们到底须要什么?

先让咱们回忆一下个别的登录是如何做的呢?

对于网页,首先会呈现一个登录页面,而后呢,输出账号密码,点击登录,就会弹出胜利 / 失败的页面。

那如何去判断胜利 / 失败呢?

思考一下,最简略的办法便是拿到前端传来的数据之后便将其拿到数据中去查,看看明码是不是一样,而后给前端回复说——我找到了,他就是 XXX 或者我找不到他的记录,让他从新输出账号密码。

而后前端对此回复做出相应的操作,比方登录胜利便跳转到首页,失败让用户从新输出。

2. 手把手教你实现一个简略的 web 登录程序

①创立 web 我的项目

关上 idea,新建一个 web 我的项目

这里为了不便 jar 包的治理,抉择 maven 构造的我的项目,而后抉择从原型创立,抉择 webapp(这里只是不便,你也能够抉择空我的项目,不过会费点工夫)。

点击下一步,输出项目名称

这里抉择相应的 maven,idea 里有自带的 maven 和 jar 包仓库。

抉择实现,这样一个最简略的我的项目构造就进去了。

接下来须要配置一下 pom.xml,因为要用到 jdbc 和 tomcat 的 jar 包(毕竟都是调用人家的接口)

(加在 project 标签里就行),下面配置的意思就是导入两个第三方工具包

②编写简略的登录页面

这里我既想要难看,又想偷懒,所以用了 layui 框架的模板

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title> 后盾治理 - 登陆 </title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta http-equiv="Access-Control-Allow-Origin" content="*">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <link rel="stylesheet" href="../lib/layui-v2.6.3/css/layui.css" media="all">
    <!--[if lt IE 9]>
    <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>
        .main-body {top:50%;left:50%;position:absolute;-webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);transform:translate(-50%,-50%);overflow:hidden;}
        .login-main .login-bottom .center .item input {display:inline-block;width:227px;height:22px;padding:0;position:absolute;border:0;outline:0;font-size:14px;letter-spacing:0;}
        .login-main .login-bottom .center .item .icon-1 {background:url(../images/icon-login.png) no-repeat 1px 0;}
        .login-main .login-bottom .center .item .icon-2 {background:url(../images/icon-login.png) no-repeat -54px 0;}
        .login-main .login-bottom .center .item .icon-3 {background:url(../images/icon-login.png) no-repeat -106px 0;}
        .login-main .login-bottom .center .item .icon-4 {background:url(../images/icon-login.png) no-repeat 0 -43px;position:absolute;right:-10px;cursor:pointer;}
        .login-main .login-bottom .center .item .icon-5 {background:url(../images/icon-login.png) no-repeat -55px -43px;}
        .login-main .login-bottom .center .item .icon-6 {background:url(../images/icon-login.png) no-repeat 0 -93px;position:absolute;right:-10px;margin-top:8px;cursor:pointer;}
        .login-main .login-bottom .tip .icon-nocheck {display:inline-block;width:10px;height:10px;border-radius:2px;border:solid 1px #9abcda;position:relative;top:2px;margin:1px 8px 1px 1px;cursor:pointer;}
        .login-main .login-bottom .tip .icon-check {margin:0 7px 0 0;width:14px;height:14px;border:none;background:url(../images/icon-login.png) no-repeat -111px -48px;}
        .login-main .login-bottom .center .item .icon {display:inline-block;width:33px;height:22px;}
        .login-main .login-bottom .center .item {width:288px;height:35px;border-bottom:1px solid #dae1e6;margin-bottom:35px;}
        .login-main {width:428px;position:relative;float:left;}
        .login-main .login-top {height:117px;background-color:#148be4;border-radius:12px 12px 0 0;font-family:SourceHanSansCN-Regular;font-size:30px;font-weight:400;font-stretch:normal;letter-spacing:0;color:#fff;line-height:117px;text-align:center;overflow:hidden;-webkit-transform:rotate(0);-moz-transform:rotate(0);-ms-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0);}
        .login-main .login-top .bg1 {display:inline-block;width:74px;height:74px;background:#fff;opacity:.1;border-radius:0 74px 0 0;position:absolute;left:0;top:43px;}
        .login-main .login-top .bg2 {display:inline-block;width:94px;height:94px;background:#fff;opacity:.1;border-radius:50%;position:absolute;right:-16px;top:-16px;}
        .login-main .login-bottom {width:428px;background:#fff;border-radius:0 0 12px 12px;padding-bottom:53px;}
        .login-main .login-bottom .center {width:288px;margin:0 auto;padding-top:40px;padding-bottom:15px;position:relative;}
        .login-main .login-bottom .tip {clear:both;height:16px;line-height:16px;width:288px;margin:0 auto;}
        body {background:url(../images/loginbg.png) 0% 0% / cover no-repeat;position:static;font-size:12px;}
        input::-webkit-input-placeholder {color:#a6aebf;}
        input::-moz-placeholder {/* Mozilla Firefox 19+ */            color:#a6aebf;}
        input:-moz-placeholder {/* Mozilla Firefox 4 to 18 */            color:#a6aebf;}
        input:-ms-input-placeholder {/* Internet Explorer 10-11 */            color:#a6aebf;}
        input:-webkit-autofill {/* 勾销 Chrome 记住明码的背景色彩 */            -webkit-box-shadow:0 0 0 1000px white inset !important;}
        html {height:100%;}
        .login-main .login-bottom .tip {clear:both;height:16px;line-height:16px;width:288px;margin:0 auto;}
        .login-main .login-bottom .tip .login-tip {font-family:MicrosoftYaHei;font-size:12px;font-weight:400;font-stretch:normal;letter-spacing:0;color:#9abcda;cursor:pointer;}
        .login-main .login-bottom .tip .forget-password {font-stretch:normal;letter-spacing:0;color:#1391ff;text-decoration:none;position:absolute;right:62px;}
        .login-main .login-bottom .login-btn {width:288px;height:40px;background-color:#1E9FFF;border-radius:16px;margin:24px auto 0;text-align:center;line-height:40px;color:#fff;font-size:14px;letter-spacing:0;cursor:pointer;border:none;}
        .login-main .login-bottom .center .item .validateImg {position:absolute;right:1px;cursor:pointer;height:36px;border:1px solid #e6e6e6;}
        .footer {left:0;bottom:0;color:#fff;width:100%;position:absolute;text-align:center;line-height:30px;padding-bottom:10px;text-shadow:#000 0.1em 0.1em 0.1em;font-size:14px;}
        .padding-5 {padding:5px !important;}
        .footer a,.footer span {color:#fff;}
        @media screen and (max-width:428px) {.login-main {width:360px !important;}
            .login-main .login-top {width:360px !important;}
            .login-main .login-bottom {width:360px !important;}
        }
    </style>
</head>
<body>
<div class="main-body">
    <div class="login-main">
        <div class="login-top">
            <span>LayuiMini 后盾登录 </span>
            <span class="bg1"></span>
            <span class="bg2"></span>
        </div>
        <form class="layui-form login-bottom" action="/login" method="post">
            <div class="center">
                <div class="item">
                    <span class="icon icon-2"></span>
                    <input type="text" name="uname" lay-verify="required"  placeholder="请输出登录账号" maxlength="24"/>
                </div>

                <div class="item">
                    <span class="icon icon-3"></span>
                    <input type="password" name="pwd" lay-verify="required"  placeholder="请输出明码" maxlength="20">
                    <span class="bind-password icon icon-4"></span>
                </div>

            </div>
            <div class="tip">
                <span class="icon-nocheck"></span>
                <span class="login-tip"> 放弃登录 </span>
                <a href="javascript:" class="forget-password"> 遗记明码?</a>
            </div>
            <div class="layui-form-item" style="text-align:center; width:100%;height:100%;margin:0px;">
                <button class="login-btn" type="submit" lay-submit=""lay-filter="login"> 立刻登录 </button>
            </div>
        </form>
    </div>
</div>
<div class="footer">
    ©版权所有 2014-2018 叁贰柒工作室 <span class="padding-5">|</span><a target="_blank" href="http://www.miitbeian.gov.cn"> 粤 ICP 备 16006642 号 -2</a>
</div>
<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<script>
    // 本来想用 json 的 post 发送,后果发现后端数据得本人解析,为了升高难度,间接用 form 表单的 post 提交,这样后端间接拿数据即可(不然还得解析 Json 数据)// layui.use(['form','jquery'], function () {
    //     var $ = layui.jquery,
    //         form = layui.form,
    //         layer = layui.layer;
    //
    //     // 登录过期的时候,跳出 ifram 框架
    //     if (top.location != self.location) top.location = self.location;
    //
    //     $('.bind-password').on('click', function () {//         if ($(this).hasClass('icon-5')) {//             $(this).removeClass('icon-5');
    //             $("input[name='pwd']").attr('type', 'password');
    //         } else {//             $(this).addClass('icon-5');
    //             $("input[name='pwd']").attr('type', 'text');
    //         }
    //     });
    //
    //     $('.icon-nocheck').on('click', function () {//         if ($(this).hasClass('icon-check')) {//             $(this).removeClass('icon-check');
    //         } else {//             $(this).addClass('icon-check');
    //         }
    //     });
    //
    //     // 进行登录操作
    //     form.on('submit(login)', function (data) {
    //         data = data.field;
    //         if (data.uname == '') {//             layer.msg('用户名不能为空');
    //             return false;
    //         }
    //         if (data.pwd == '') {//             layer.msg('明码不能为空');
    //             return false;
    //         }
    //         $.ajax({
    //             url:'/login',
    //             method:'post',
    //             data:data,
    //             dataType:'JSON',
    //             success:function(res){//                 if (res.msg==='登录胜利'){//                     layer.msg('登录胜利', function () {
    //                         window.location = '../index.html';
    //                     });
    //                 }else {//                     layer.msg("登录失败");
    //                 }
    //             },
    //             error:function (data) {//}
    //         }) ;
    //
    //
    //         return false;
    //     });
    // });
</script>
</body>
</html>

当然以上代码有一部分正文掉了,起因是如果用 JSON 格局发送 post 申请,后端的 servlet(精确的说是 Tomcat 的解析)并没有帮咱们解析封装这部分数据,所以咱们无奈间接 get 到,得本人另外解析数据,当然也有一些第三方的工具包能够帮咱们做这些事件(如阿里的 fastjson 等),这里为了使其更加简略,所以采纳表单提交 post 申请的形式,这样解析的工作就不必咱们做了。

成果是这样的:

如果你没学过 layui 或者对前端不太行,你也能够这样

一样的性能,不过看上去的成果就不怎么好了。

③编写 servlet 程序

当有了前端的页面,看上去好了很多,但本质校验的程序咱们还没有写。

设想一下咱们就是后端程序,以后端的数据历经艰险,从盘根错节的网络中达到咱们的服务器,而后通过零碎散发到相应端口,这时恰在此端口的 tomcat 程序承受到了 HTTP 申请并对其封装,通过一系列骚操作后散发到了咱们手中,而咱们要做的就是拿着这个封装好的申请进行校验操作,而后对返回对象进行相应批改。而这也是 servlet 类所须要做的。

package com.dreamchaser.loginTest;

import com.dreamchaser.loginTest.mapper.UserMapper;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginServlet extends HttpServlet {static UserMapper userMapper=UserMapper.getUserMapper();

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String uname=req.getParameter("uname");
        String pwd=req.getParameter("pwd");
        ServletOutputStream outputStream = resp.getOutputStream();
        String result;
        if (pwd.equals(userMapper.getPwdByName(uname))){
            // 响应
            result="登录胜利";
        }else {result="登录失败";}
        outputStream.write(result.getBytes());
    }
}

你可能会纳闷这个 UserMapper 是什么,别急,前面会介绍。

④封装 jdbc 操作,编写简略的数据库连接池

在操作数据库之前,最好写个简略的数据库连接池。一个是简化咱们的操作,一个是节俭开销,进步性能(Connection 是个十分消耗资源的对象,频繁的创立和回收将会是一笔微小的开销)



当然上述实现十分简陋,并发性能也不是很好,高并发时可能还会产生 OOM,不过凑活着用吧。

⑤操作数据库


这里采纳单例的设计模式,保障 UserMapper 对象只有一个。(十分简陋,实现也不优雅,看着本人的代码,忽然感觉框架好不便啊)

这里的作用就是依据用户名查问明码。

⑥配置 web.xml

尽管写了 servlet,然而 tomcat 并不知道你这个 servlet 的类在哪啊,所以必须让 tomcat 晓得,配置 web.xml 的目标就是告诉 tomcat 在哪(更精确的说是 servlet 容器)的一种形式(当然也能够用注解)。配置如下:

servlet-class 里写你这个 Servlet 类的门路即可。

⑦idea 运行配置

idea 配置还是比拟不便的。

点击编辑配置

点击 +(增加按钮),抉择 tomcat 服务器(选哪个都能够,我选了 tomcat 本地)

而后抉择相应的服务器程序,配置我的项目拜访的端口,就是 tomcat 在哪个端口运行(留神不要占用已有端口,默认 8080,我这里是因为 8080 被占了,所以用了 9090)

这里还得配置一下工件,因为我的项目要运行个别有两种形式:

一种是打成 war 包放在 tomcat 的 webapps 目录下

一种是打成 jar 包间接运行(SpringBoot 就是用这种形式,因为它内置 tomcat)

这里工件的作用就是打成 war 包,至于每次运行部署?idea 都会帮你搞定!是不是很不便?

这里那个应用程序上下文的作用就是给拜访门路加个前缀

个别间接写成 ”/” 就行了,这样咱们要拜访 login.html,是不是很不便?

⑧运行程序

点击运行


拜访胜利,试试账号密码。

我当初数据库里只有 root 这一条数据,试试成果

输出谬误的明码

输出正确的明码

到这里,咱们松了一口气,终于实现了简略的登录性能。

三、回顾改善

别急,咱们尽管实现了登录这个性能,然而这个实现切实太简陋了,各方各面都没思考,返回页面也只登录胜利,登录失败的提醒。

咱们回顾一下,认真想想有哪些问题,

1. 明码加密裸奔

2. 登录信息未存储

四、用 SpringBoot+SSM 实现一套简略的鉴权服务(注册,登录,权限管制)

小结

看到一个题目要求写个简略 web 登录程序,意思是用 servlet、jsp 和 jdbc 实现。本着要么不做,要做就要做好的准则,我开始着手实现此次题目(其实也是写实训的用户鉴权局部),而之前也有相干教训,这次正好能派上用场。

今日份分享已完结,请大家多多包涵和指导!

正文完
 0