今日の共有が始まります、もっとアドバイスをお願いします〜
今日のほとんどのシステムには独自の認証サービスがあります。これは、ユーザーがシステムと対話するための最初のステップです。システムには、ユーザーが誰で、何ができるかを理解するための一連のステップが必要です。これらを理解すると、より良いサービスを提供できます。
1.認証サービスとは
認証とは、ユーザーがシステムにアクセスする権利を持っているかどうかを確認することです。
認証には2つの側面があります。
- ユーザー認証。ネットワークはユーザーを認証して、違法なユーザーがネットワークリソースを占有するのを防ぎます。
- ネットワーク認証。ユーザーはネットワークを認証して、ユーザーが違法なネットワークにアクセスしたり、重要な情報を詐取したりするのを防ぎます。
ここでの認証とは、主にユーザー認証、つまり「あなたがあなたである」ことを確認する方法を指します。最も単純な実施形態は、通常のユーザーログインおよびログアウトである。
次に、servlet + jdbcを使用して、単純なユーザーログインプログラムを実装します。
1.明確なアイデア
まず、何が必要かを慎重に考える必要がありますか?
まず、一般的なログインがどのように行われるかを思い出してみましょう。
Webページの場合、最初にログインページが表示され、次にアカウントパスワードを入力し、[ログイン]をクリックすると、成功/失敗ページがポップアップ表示されます。
成功/失敗を判断する方法は?
考えてみてください。最も簡単な方法は、フロントエンドからデータを取得し、データをチェックしてパスワードが同じかどうかを確認してから、フロントエンドに返信して、「見つけた、彼はXXXです」と言うことです。または私彼の記録が見つからない場合は、アカウントのパスワードを再入力するように依頼してください。
次に、フロントエンドはこの応答に対して対応する操作を行います。たとえば、ログインが成功した場合はホームページにジャンプし、失敗した場合はユーザーが再入力します。
2.簡単なWebログインプログラムを実装する方法を教えます
①Webプロジェクトを作成する
アイデアを開き、新しいWebプロジェクトを作成します
ここで、jarパッケージの管理を容易にするために、Maven構造のプロジェクトを選択し、次にプロトタイプから作成することを選択し、Webアプリを選択します(これは便宜上ですが、空のプロジェクトを選択することもできますが、しばらく時間がかかります)。
[次へ]をクリックして、プロジェクト名を入力します
ここで、対応するMavenを選択すると、アイデアには独自のMavenおよびjarパッケージウェアハウスがあります。
選択して完了すると、このような最も単純なプロジェクト構造が出てきます。
次に、jdbcとtomcatのjarパッケージが使用されるため、pom.xmlを構成する必要があります(結局のところ、これらはすべて他を呼び出すインターフェイスです)
(プロジェクトタグに追加するだけです)、上記の構成は、2つのサードパーティツールキットをインポートすることを意味します
②簡単なログインページを書く
ここでは見栄えを良くして怠惰になりたいので、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完成。本着要么不做,要做就要做好的原则,我开始着手完成此次题目(其实也是写实训的用户鉴权部分),而之前也有相关经验,这次正好能派上用场。
今日份分享已结束,请大家多多包涵和指点!