登录接口实现细节分析与登录接口代码实现
Posted 生产队的大驴and小乌贼来了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了登录接口实现细节分析与登录接口代码实现相关的知识,希望对你有一定的参考价值。
登录接口实现细节分析
登陆接口
接下我们需要自定义登陆接口,然后让SpringSecurity对这个接口放行,让用户访问这个接口的时候不用登录也能访问。
在接口中我们通过AuthenticationManager的authenticate方法来进行用户认证,所以需要在SecurityConfig中配置把AuthenticationManager注入容器。
认证成功的话要生成一个jwt,放入响应中返回。并且为了让用户下回请求时能通过jwt识别出具体的是哪个用户,我们需要把用户信息存入redis,可以把用户id作为key。
登录接口代码实现
package com.example.qinghuatokendemo.Controller; import com.example.qinghuatokendemo.Domain.ResponseResult; import com.example.qinghuatokendemo.Domain.User; import com.example.qinghuatokendemo.Service.LoginServcie; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController public class LoginController @Autowired private LoginServcie loginServcie; @PostMapping("/user/login") public ResponseResult login(@RequestBody User user) //登录 return loginServcie.login(user);
package com.example.qinghuatokendemo.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter //创建BCryptPasswordEncoder注入容器 @Bean public PasswordEncoder passwordEncoder() return new BCryptPasswordEncoder(); @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception return super.authenticationManagerBean(); @Override protected void configure(HttpSecurity http) throws Exception http //关闭csrf .csrf().disable() //不通过Session获取SecurityContext .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() // 对于登录接口 允许匿名访问 .antMatchers("/user/login").anonymous() // 除上面外的所有请求全部需要鉴权认证 .anyRequest().authenticated();
package com.example.qinghuatokendemo.Service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.example.qinghuatokendemo.Domain.LoginUser; import com.example.qinghuatokendemo.Domain.User; import com.example.qinghuatokendemo.Mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import java.util.Objects; @Service public class UserDetailsServiceImpl implements UserDetailsService @Autowired private UserMapper userMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException //查询用户信息 LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(User::getUserName,username); User user = userMapper.selectOne(queryWrapper); //如果没有查询到用户就抛出异常 if (Objects.isNull(user)) throw new RuntimeException("用户名或者密码错误"); //查询对应的权限信息 //把数据封装成UserDetails返回 return new LoginUser(user);
打开redis以后
测试接口
Android——MVCMVPMVVM框架实现登录示例
MVC、MVP、MVVM框架实现登录示例
MVC
描述
自如其意,MVC分为三部分:M层、V层、C层。
M层:model层,主要用于逻辑处理。
V层:view层,主要指Activity、Dialog、Fragment,用于视图展示。
C层:controller层,用于视图层与数据层交互,此处由Activity充当。
缺点
视图层与数据层没有完成解耦,随着逻辑增多,会使Activity非常拥堵。
优点
比一个文件闯天下,稍微好一点
MVP
效果图
描述
自如其意,MVP分为三部分:M层、V层、P层。
M层:model层,主要用于逻辑处理。
V层:view层,主要指Activity、Dialog、Fragment,用于视图展示。
P层:presenter层,用于视图层与数据层交互。通过接口实现交互。
缺点
随着逻辑增多,用于实现视图层与数据层交互的接口数据就会增多
优点
数据层与视图层完成解耦
代码解析
视图效果图
建立实体类
public class User{
private String UserName;
private String PassWord;
public User(String UserName,String PassWord){
this.PassWord = PassWord;
this.UserName = UserName;
}
public User(){
}
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public String getPassWord() {
return PassWord;
}
public void setPassWord(String passWord) {
PassWord = passWord;
}
}
建立实体类接口
public interface IUser {
boolean LoginAccount(String userName,String passWord);
}
实现实体类接口
public class exeLogin implements IUser {
private User user;
@Override
public boolean LoginAccount(String userName,String passWord) {
if (userName.equals( "admin" ) && passWord.equals( "123456" )){
user = new User( );
user.setUserName( userName );
user.setPassWord( passWord );
return true;
}
return false;
}
}
设置P层
public class LoginPresenter {
private exeLogin exeLogin;
private IMain iMain;
public LoginPresenter(IMain iMain){
this.iMain = iMain;
exeLogin = new exeLogin();
}
public void Login(){
String userName = iMain.getUserName();
String passWord = iMain.getPassWord();
boolean isSuccess = exeLogin.LoginAccount( userName,passWord );
iMain.Login( isSuccess );
}
}
建立交互接口
public interface IMain {
String getUserName();
String getPassWord();
void Login(Boolean isLoginSuccess);
}
数据绑定
public class MainActivity extends AppCompatActivity implements IMain{
private EditText userName,passWord;
private Button btnLogin;
private Context context = null;
private LoginPresenter loginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
InitView();
Listener();
}
private void InitView(){
userName = findViewById( R.id.username );
passWord = findViewById( R.id.password );
btnLogin = findViewById( R.id.login );
loginPresenter = new LoginPresenter( this );
if (context == null){
context = MainActivity.this;
}
}
private void Listener(){
btnLogin.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
loginPresenter.Login();
Log.d( "TAG","click success" );
}
} );
}
@Override
public String getUserName() {
return userName.getText().toString().trim();
}
@Override
public String getPassWord() {
return passWord.getText().toString().trim();
}
@Override
public void Login(Boolean isLoginSuccess) {
if (isLoginSuccess){
Toast.makeText( MainActivity.this,"Success",Toast.LENGTH_SHORT ).show();
Log.d( "TAG","Success" );
}else {
Toast.makeText( MainActivity.this,"Fail",Toast.LENGTH_SHORT ).show();
Log.d( "TAG","Fail" );
}
}
}
MVVM
效果图
描述
Model层:
数据处理
View层
实体
ViewModel:
实现视图与数据的交互,将二者分离,实现解耦
代码解析
导入dataBinding
dataBinding {
enabled = true
}
实体类
public class User extends BaseObservable {
public String mUserName;
public String mPassWord;
public User(){
}
public User(String mUserName,String mPassWord){
this.mUserName = mUserName;
this.mPassWord = mPassWord;
}
@Bindable
public String getmUserName() {
return mUserName;
}
/**
* @param mUserName */
public void setmUserName(String mUserName) {
this.mUserName = mUserName;
notifyPropertyChanged( BR.mUserName );
}
@Bindable
public String getmPassWord() {
return mPassWord;
}
/**
* @param mPassWord */
public void setmPassWord(String mPassWord) {
this.mPassWord = mPassWord;
notifyPropertyChanged( BR.mPassWord );
}
}
添加 @Bindable,作为xml绑定字段
@Bindable
public String getmUserName() {
return mUserName;
}
BR是一个自动生成的类,大致内容为将每一个字段添加ID,通过notifyPropertyChanged实现数据更新
/**
* @param mUserName */
public void setmUserName(String mUserName) {
this.mUserName = mUserName;
notifyPropertyChanged( BR.mUserName );
}
建立viewmodel
public class ViewModel {
private ActivityMainBinding binding;
public User user;
public ViewModel(ActivityMainBinding binding,User user){
this.binding = binding;
this.user = user;
}
public void Login(View view){
if (user.getmUserName().equals( "admin" ) && user.getmPassWord().equals( "123456" )){
Log.d( "TAG","success" );
}else {
Log.d( "TAG","fail" );
}
Log.d( "TAG",user.getmUserName()+"" );
Log.d( "TAG",user.getmPassWord()+"" );
}
}
xml绑定数据
注意视图绑定数据层字段时,一个等于=符号产生不同结果,如果没有等于,我在输入框输入的数据,实体类数据不会刷新,加上等号,完成数据双向绑定。
密码输入框中输入123456
android:text="@={viewmodel.user.mPassWord}"
密码输入框中输入123456,而打印出来是12345,并没有完成双向绑定
android:text="@{viewmodel.user.mPassWord}"
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.franzliszt.mvvmtest.model.User" />
<variable
name="viewmodel"
type="com.franzliszt.mvvmtest.viewmodel.ViewModel" />
</data>
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="40dp">
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="30dp"
android:text="账号密码登录"
android:textColor="#000000"
android:textSize="30sp"
android:layout_marginTop="20dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="20dp">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="用户名"
android:paddingLeft="10dp"
android:singleLine="true"
android:textColor="#ff000000"
android:textSize="15sp"
android:text="@={viewmodel.user.mUserName}"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="10dp"
android:hint="密 码"
android:paddingLeft="10dp"
android:password="true"
android:textColor="#ff000000"
android:textSize="15sp"
android:text="@={viewmodel.user.mPassWord}"
/>
</LinearLayout>
<Button
android:id="@+id/login"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginLeft="80dp"
android:layout_marginTop="10dp"
android:background="#1A73E8"
android:text="登录"
android:textColor="#ffffff"
android:textSize="15sp"
android:onClick="@{viewmodel.Login}"/>
</LinearLayout>
</layout>
视图与数据绑定
初始化User类的数据, 完成视图与数据绑定
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
binding = DataBindingUtil.setContentView( this,R.layout.activity_main );
user = new User( "admin","12345" );
binding.setViewmodel( new ViewModel( binding,user ) );
}
}
以上是关于登录接口实现细节分析与登录接口代码实现的主要内容,如果未能解决你的问题,请参考以下文章