00:00
各位同学大家好,咱们下面呢,继续使用完成项目中的用户认证。咱们刚才呢,完成了核心组件中的两部分,第一个登录过滤器,就是校验用户名密码是否正确生成token,然后第二个认证解析token的组件,判断请求里边有没有token,如果有完成认证,没有的话,提示信息,这一点完成之后,下面呢我们来做第三部分,在配置类里边来配置相关的信息,那下面呢,我们开始做第三部分。咱们看到啊,我们在这个模块里边,我们之前写过一个配置类叫做web,然后这个配置类一个类在上面加入相关的注解,那咱们下面呢,在里边加上相关的配置内容,这个配置内容呢,我在课件中给大家写好了一段内容,那我们从课件中把这内容咱们复制过来,然后我们一行一行给大家解释一下这个内容是什么意思。
01:05
我这里说明啊,这个配置过程呢,是一个固定的一个格式,这个格式也不是我写的,我是从它的官网复制,然后改成我们实际效果,所以各位自己在用的时候,你也可以把这个结构复制,然后根据你的项目实际把它做个修改就可以了,这个没必要一行一行写一遍,但是你要能看懂每行的含义,根据实际来完成修改,那我下面啊把这个做个复制。复制到我们这个配置类里边来。复制之后,咱们下面啊,给他做这么一个相关的解释。这些啊,先给它去掉,因为我这里边有这个啊,先拿掉,然后下面呢,我们来一行一行解释一下它是什么意思啊,首先大家看configuration代表配置类啊,咱之前都知道这是我们基础部分,然后第二个叫做开启security的默认行为,用unable web,然后在面来看啊,在里边我们注入了两个一个。
02:07
这各位应该清楚啊,User details service在这里边有什么,大家想一下,咱们应该刚讲过有什么,咱们是不是有个方法,根据用户名称,然后查询我们的用户信息,咱是写了这么一个方法,然后这里边还有一个叫custom MD password个校验部分,然后把它注入之来看啊,在这个我们一个什么意思呢?就是得到我们这个对象叫。Authentication manager把这对象得到,然后得到之后里面有一个conig方法,在方法中来配置哪些接口开启防护,哪些绕过防,就是哪些需要判断是否登录,哪些需要不径判断,那我们来看啊,首先第一部分关闭这个跨站请求,伪造开启跨域跨方便咱们访问,这里边设置你的登录接口,大家看啊。
03:08
这个是我们登录接口,你看到啊,我们录口应该是在置咱们的径是login systemex log是咱的登录,因为登录接口他不需要做判断,所以然给他就是打开,让他直接完成登录,而这里边其他接口都需要完成认证之后才能访问。这应该我说清楚了啊,我再说一遍,登录接口肯定不需要进行判断,因为你还没有登录,肯定它没有这个状态,而其他接口你只有登录之后才能进行访问,下面呢,加上咱们写这个就是相关的这个组件,比如说我们现在在操作之前,我们都进行判断它是否是登录这个filter,咱之前写到的啊,在里边我们判断请求头里边有没有token字符串,有的话完成登录,没有的话我们表示失败。
04:04
之后呢,这是我们登录的这个在登录里边就是做这个校验啊,然后调方法进行实现。这是我们做配置,另外我们这过程中,因为咱们做的是前后端分离开发,基于token进行操作,所以这里边我们没有用到session,把session我们就禁用掉了。在这个方法中指定我们的user detail service和咱们的加密器,最后咱可以设置哪些请求进行拦截判断,比如说我们这里边这个S相关的,包括相关的这里边我们给它加上,如果你再有其他的在里边依次可以加上。以上就是咱们的配置类部分,各位按照这个结构改成你的效率就可以了。然后这个之后呢,我们现在用spring security完成用户认证,把这个相关部分应该我们就完成了。然后这个完成之后,咱们最后呢,开始进行最终的测试,我这里也写到了啊,刚才我解释过,因为我们项目是基于前后端分离开发的,我们是用JWT生成token字符串,所以咱操作中我们这里边没有用到那个表单的那个就是form log啊,登录的表单session我们也做了禁用,咱们这里边跟session无关,我们是基于这个ton,通过客户端啊,里边传递这个值请求头传递来维护这个登录状态,咱之前也提到过啊,这个各位明确。
05:34
然后这个之后下面呢,我把这服务启动,我们进行测试,就试一下咱们当前效果怎么样,然后说一下怎么试啊,咱们通过两个方面,第一个我一会儿直接访问一个接口路径,因为咱们目前没有登录,它会返回我们这个信息,然后第二个我们在swag里边,或者说耐这里边进行登录,咱们通过加断点一步执行,看它是否满足我们预期的执行效果,那下面我们开始做这个测试。
06:07
首先大家看啊,我现在把这个服务先进行启动,然后启动过程中呢,这里边报了一个错啊,咱们看一下这个错误是什么,咱先解决一下,然后进行测试。咱们往下来找啊,看这提示到底是什么,各位往下来看,各位看这位置啊,他说这个user details service。然后我后来说这个类它出了问题,所以在里边怎么样?Found就是我们现在这个user detail service,它不到这个位置出错了,那到底在哪里,我们看的细点啊,说在我们这个web里,这个user detail这个找不到,那咱们定位到问题中来,首先这是我们的配置类,在配置类中我们找到这个user。这个detail service说这有问题,让大家看一下什么问题啊,我这里特别说明啊,这个问题呢,是我要特别演示的问题,因为每次到这个地方,很多同学在自己演示过程中,或者自己在练习过程中,一般问题经常都是出在这个位置,所以下面我这个再重复一遍啊,这个问题咱先再看一遍。
07:21
问题提示就是在我们的配置类里边,Web中告诉我们user service这个找不到,这也是我们在整合这个spring security中用户认证模块中经常遇到问题,之前很多同学每天到这里都会出现这个问题,那咱们下面做一个详细说明,这问题为什么产生,然后怎么解决。那我们来看啊这个特点。首先啊,我们看啊,User details service咱们发现啊,我这里边引入了一个包,这个配置类呢,我是从课件中是不是直接复制过来的,这个类肯定没有错,但是大家这个包它是哪个里边的,User detail service是哪个里边的。
08:08
我们看到啊,不是我们写的吧,是这个里边的这个user service们打是所里应该是这个类型,而现在比如说你传类型之后,为什么他说找不到,因为咱们写的过程中,我们好像啊,大家看啊,这是一个什么接口,咱们的。实现类中好像没有实现这个接口,而我们怎么做,我们是不是自己写了一个接口,也叫这个名字,然后咱对它进行实现,但是有同学说啊,说老师你把这个改成我们自己的,可不可以咱们改一下啊,把这个我先去掉,我给他先注掉啊,我咱一会儿写的方便,然后把它的包给他改一下,改成咱们自己这个过来。这是我们自己的,你看啊,就是他,然后改完之后咱们往下看,看到问题了吧,这里是报错了,他让我们传的是什么,它它本身的那个user details service,而不要传我们自己这个,那大家说这个该怎么解决?
09:09
这问题我不知道是否说清楚了啊,首先第一个user details service,这是它本身这个接口,但是咱们刚才写的时候呢,没有实现这个接口,我们没有实现,而咱是自己写的一个相同名称接口,我们传的时候呢,他以后咱们用的他自己的这个service,而咱传我们写的这个肯定是不对,里面报错了,所以咱们把这个需要给他解决一下啊,就特别强调。各位写的时候注意,这个不要传错啊,传的是里边这个user service,不要传自己这个,那现在有问题了,因为咱没有实现它,那怎么做,说它的解决方式啊,有多种方式,第一种方式就是你可以自己啊不写这接口,然后咱们在实现类里边,我找到实现类,就是它在实现类中怎么做实现它里边那个user detail service,就是把这个给它改一下,比如现在啊,我们来改一下。
10:07
改成谁里边这个user比t service,这样的话就可以解决,这是第一种方式,但是咱之前是自己创建的,我为了各位看的更明确,比如说我现在啊,就想用我自己这个service,那怎么做,这也很简单,你找到我们自己写的这个user detail service,让他继承下本身那个service,我来写一下啊,继这个里边的user detail service,这样的话就可以解决,包括你在方法上你可以加上一个overri。这注解我不重复了啊,这个我应该很清楚,是一个Java中的技术注解,所以现在这么做可以解决,说的简单点啊,咱们在配类中要传入里边这个user detail service的实验类对象,而咱的做法就是第一种方式,你的实验类可以继承里边这个接口,另外你自己写接口,让你的接口继承这个user detail service,通过它经实现,这样的话,这问题就可以解决,要不然提示说这个东西找不到,这是我们特别说的问题啊,就注意这个传的话,你的这个类型不要传错,也是各位经常遇到一个问题,我们目前这么做,虽然这么做可能不是特别好,你可以不建这个类,在你的实验类中直接实现四分钟的个接口都是可以是做到的啊,我们这个公的。
11:34
在这个我们就说完了啊,然后说完之后下面呢,我把这服务器我们再重新启动,我们再试一下,看一下最后的结果啊。就是一个问题的出现啊,有多种解决方式,只是有的时候呢,我为了各位更好理解,所以我这里自己建立一个接口,解是实验类,但是咱们让他要变成我们框架里边这个类型,所以咱们最简单做法让他继承这个就可以了,或者说你不写这个,让实现类实现四分钟,这个接口也同样可以做到现在完成啊,完成之后我们这里边来做一个测试,咱们试一下这个效果啊。
12:11
然后怎么测试呢?第一个我们现在啊,来访问一下我们这个项目中的某一个接口,咱随便访问一个啊,比如我就访问这个接口就是它啊我把这个。复制一下。复制之后来到我的浏览器中直接回车,大家看啊,提示我们什么是不是叫认证失败,也就是说现在啊,我的登录是失败了,登录失败呢,它会返回我们那个失败的信息,也是咱们之前写的里边的这个部分。就是他。你之前写过啊,204认证失败。把这个进行返回,所以现在证明咱这个认证过程就生效了,你没有登录它最终提示你认证失败,或者说登录失败。现在这就完成了啊,所以咱们完成了第一部分测试。
13:02
然后这个之后呢,下面呢,我们通过swag再做个测试,这个测试我们这么来做,在里边加上断点,我们用断点调试方式进行最终测试,看它是否符合我们预期的这个效果,那咱们下面啊给他来试一下啊。首先我在里边呢,加上点然点,怎么咱加这个方第一个Ken log,因为在里是到咱们来到里到你入这进行这个认,如果功到咱们这里边来,如果失败到这个方案中来,咱在里边加上断点啊,这是我们加的第一部分,然后第二部分每次访问接口的时候,在里边要做这个校验啊,在校验过程中我们做了一些相关的这个设置。咱就加到这里边啊,判断请求头里边有没有你相关这个值,如果有的话那就是登录,没有的话那就不是登录啊,通过它进行实现,然后最终放到我们的上下文对象中去,这里边会加上。
14:12
这是我们写到的啊,然后之后在里边还有一个方法,因为咱们要根据用户名进行查询,就是我们这个接口的实现类咱们找到啊,在接口实现类中我们写的这个方法,根据用户名称查询返回我们这个就是对象的相关的这个信息啊,就是这个用户的信息把这个返回。这是我们加的几个地方,所以现在啊这些就完成,完成之后我现在用debug方式启动,然后通过那个swag to,或者说叫耐啊进行最终的测试一下是否满足们的结果。等他啊,先启动起来。现在啊已经启动了,然后咱们打开我们这个那。
15:01
Doc。点HTML回车,然后咱们进入啊在里边我们怎么来看呢?注意啊,这位置呢,我们就访问下我们这个登录的这个接口登录,因为咱们提到啊,登录的时候呢,肯定不需要校验,你登录之后再访问其他接口才完成校验,所以咱们用它来做一个测试,我们下面啊来试一下这个效果是怎么样的。那我们怎么测试呢?首先啊,我们找一个用户名和密码,用户名我们就写个李四,密码是六个一。六个一啊,这之前我们的用户密码应该有这数据,然后下面我们看这个效果啊,现在我点击发送,各位看到我在断点中是不是生效了,各位看啊,它是怎么做的,首先第一部分到我们这个Ken authen里做一个判断,就判断是否需要校,因为咱们做了处理,如果说你是登录,那就直接放行,不是登录做了一个过程,那现在我们是登录,所以他直接就放过去啊,包括就做了一个放行,咱直接跳到下一部分。
16:08
然后下一部分各位看到哪里到了我们的token low in filter里边要做的一个登录,在登录里边,首先第一部分在这个a type authentication里边得到我们的用户信息,我们看啊,Log in view里是不是有用户名密码,我们清楚看到已经取到了啊,到之后在这过程中我们进行封装。封装之后呢,它会调用框架中这个方法叫aluthenic k完成这个认证啊,这个流程咱之前看过了啊,它里边是由spring security做到的,然后认证过程中我们看啊,它会去根据用户名来查我们的这个用户信息,查出用户信息之后最终返回校验你的密码,咱们这里边写的是查的过程,就查这个数据过程,校验过程是还是有框架做到的,然后咱们往下执行,各位看啊,System user里边我们这个数据啊,然后下面做这个判断。
17:08
最终封装返回。然后封装反应之后,大家看啊,我们现在应该是认证成功了,但这过程中有一个校验密码过程,也是由框架做到,今天咱们看过流程,如果成功到这个successful这个方法中,在方法中我们得到当前的用户啊,根据用户名,根据ID和用户名生成token,把它放到map中,最终进行返回,所以以上啊就是一个认证的过程,然后各位看啊,最终返回的有咱们的信息,包括这个。基本的200成功,还有这个token,所以现在啊,你发现啊,跟咱们预期的效果应该就是一致的,这个我们就完成,完成之后我们再来看啊,比如现在我现在试一下这个info啊,Info里边呢,目前咱没有带这个头信息,咱就直接试一下,比如现在我点发送。
18:02
各位看啊,发送的时候呢,它首先也是到我们这里边,但是现在不是登录啊,他直接做这个就是校验的这个过程看。Hi中有没有ton,因为目前咱没有传啊,他这只肯定等于空,是不是等于now,等于now之后最终提示说现在你没有这个权限,或者说叫认证失败,如果你带了token,他就能完成这个后续的操作。所以以上啊,咱们就完成了认证的这个测试,通过security把这个总体过程就完成了,这个过程呢,确实要复杂点啊,因为里边涉及到有很多的事情,所以我最后呢,把这个实现认证的过程给各位再做一个强调,把里面一些细节再来重复一遍啊,要求各位能按照自己的这种习惯,把最终效果能整合出来,我这里写的呢,很多时候是按照我个人的习惯,实际中可能有不同的做法,但是总体思路肯定都是一致的,那最后啊,我们再看一遍这个过程啊,给大家继续来再来说一下啊。
19:08
首先我们看一下啊,在咱们的这张图里边,因为咱们现在要进行用户认证,在认证的时候呢,咱先看这里边啊,就是我们的。啊,往上找应该是最开始这张图里边,这是它一个总体的流程,在流程中我们快速过一遍啊,首先得到提交的用户名和密码,封装成这个authentication对象,然后他用到这个token这个事现类,这里边封装之后调用aluthen的方法进行认证,在认证过程中要调用方法就是load by username,查询用户信息,返回user detail对象进行密码校验,如果成功,最终填充回到对象中,然后把这个对象放到咱们的上下文对象中security count里面去,这是一个总体的流程,而我们在一起的时候呢,它里边的大部分框架已经帮我们做到了,比如说里面的一个就业啊,包括里面就这些过程,包括放到摄海文过程都已经做到了,咱们需要做什么呢?第一个就是登录啊,就是得到用户名密码信息,然后封装并方法,然后第二个我们判断。
20:20
就是里边是否是登录从hi中取到你的请求头信息,另外就是写这个根据用户名调方法,就是调这个方法得到这个信息的过程,其他过程基本上都是由这个框架做到的。我们刚才呢,在自定义这个过程中,首先我们写了三个组件,第一个user detail这个类,第二个写的这个根据用户名查的方法,第三个写了一个定义密码校验器。除此之外,我们写了核心组件,第一个组件就是登录,第二个解析token,就是判断你是否登录,然后第三个在配置类中配置了相关的信息,就是我们说这个流程。另外在写配置类的时候,我们刚才特别演示的一个问题,就是我们这个类型的问题,咱来看一下啊,在配置类中我们传了一个叫user detail service,这个要传的是里边的这个user detail service,如果说你是自己创建的service,也可以直接传,它的类型不一致,所以做法就是要么你让你的实验类直接实现它,或者说让你的接口继承这个。
21:29
框架里边这个user service最终都可以实现,所以以上啊,就是完成认证的过程,这个咱们就最终实现出来了。
我来说两句