Lesson16 京淘项目---单点登录系统SSO的搭建

京淘 单点登录系统 SSO

1 现状分析

当前在京淘前台页面中,点击“登录”和“免费注册”这两个按钮,跳转的网页地址分别为:
http://www.jt.com/user/login.html
http://www.jt.com/user/register.html
在这里插入图片描述
显然这是个伪静态的用法,实际上要访问的资源为:
在这里插入图片描述
要想展现对应的页面,客户端势必要发送两次ajax请求。
那么对应的controller中难道也一定得写2个方法去接收吗?
不需要,用restful风格,一个方法搞定

1.1 编辑UserController

@Controller   //涉及到页面的跳转功能(登录,注册)
@RequestMapping("/user")
public class UserController {

    /**
     * 通用页面的跳转的实现
     * 1.http://www.jt.com/user/login.html       login.jsp页面
     * 2.http://www.jt.com/user/register.html    register.jsp页面
     */
    @RequestMapping("/{moduleName}")
    public String module(@PathVariable String moduleName){
        return moduleName;   //返回的是login.jsp  register.jsp等这种形式
    }

}

1.2 页面效果展现

在这里插入图片描述
在这里插入图片描述

2 创建京淘SSO项目----JT-SSO

2.1 JT-SSO项目说明

作用:
主要为jt-web的服务器提供用户的数据的支持,但凡涉及到user的CRUD操作都应该由该系统完成.
所以势必会用到跨域访问(jt-web跨域访问jt-sso)
由于jt-sso不需要展现什么页面给客户,所以打包时,打jar包。
继承jt父级,依赖jt-common,添加插件。
端口号:8093
在这里插入图片描述

2.2 创建项目

在这里插入图片描述

2.3 编辑pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <artifactId>jt-sso</artifactId>

    <!--继承父级-->
    <parent>
        <artifactId>jt</artifactId>
        <groupId>com.jt</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!--添加jt-common依赖-->
    <dependencies>
        <dependency>
            <groupId>com.jt</groupId>
            <artifactId>jt-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--引入数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--springboot连接数据库-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <!--跳过测试类打包 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.4 编辑User的POJO对象

这个User文件要写在jt-common中
在这里插入图片描述由这个表可知,User的POJO对象有这么几个属性。其中创建时间和修改时间从BasePojo那继承即可。

@TableName("tb_user")
@Data
@Accessors(chain = true)
public class User extends BasePojo {

    @TableId(type = IdType.AUTO)  //主键自增
    private Long id;
    //用户名
    private String username;
    //密码
    private String password;
    //电话
    private String phone;
    //邮箱    暂时用电话号代替
    private String email;

}

2.5 手动补全JT-SSO的项目结构

在这里插入图片描述

2.6 编辑nginx配置文件

修改nginx之后记得重启服务器.

# 配置前台服务器
	server {
		listen 80;
		server_name  sso.jt.com;

		location / {
			proxy_pass http://localhost:8093;
		}
	}

2.7 编辑Hosts文件

在这里插入图片描述

3 用户数据校验

用户在登录时,在注册时,都需要输入很多信息。而服务器需要校验这些数据,来控制用户是否能成功登录,成功注册。

3.1 客户端的Ajax请求的url分析

在这里插入图片描述

3.2 查看JS

1.在IDEA中按CTRL+H 检索一下这个请求对应的JS代码在哪个文件中
在这里插入图片描述2.查看JSONP跨域请求是怎么写的
在jdValidate.js的第600行左右

$.ajax({
            	url : "http://sso.jt.com/user/check/"+escape(pin)+"/1?r=" + Math.random(),
            	dataType : "jsonp",
            	success : function(data) {    //返回状态信息:200(服务器干活成功)    201(服务器干活失败)
                    checkpin = data.data?"1":"0";
                    if(data.status == 200){
                        if (!data.data) {
                            validateSettings.succeed.run(option);
                            namestate = true;
                        }else {
                            validateSettings.error.run(option, "该用户名已占用!");
                            namestate = false;
                        }
                    }else{ //表示 后台服务器运行异常了,需要先通知一下客户
                        validateSettings.error.run(option, "服务器正忙,请稍后重试!");
                        namestate = false;
                    }
                }
            });

3.3 接口文档说明

一般工作中与前端工作交接时都需要接口文档,这个是很重要的一个文档!!!记录着工作量,与工作记录。
一般用PPT或WORD的方式写接口文档。
一个例子:
在这里插入图片描述

3.4 编辑jt-sso中的UserController

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 返回用户表tb_user中用户的记录
     * 返回值类型:json串
     */
    @RequestMapping("/findAll")
    public List<User> findAll(){
       List<User> userList =  userService.findAll();
       return userList;
    }

    /**
     * 需求分析:校验用户在注册框里输入的数据们 是否可以被注册
     * url:http://sso.jt.com/user/check/{param}/{type}
     * 参数:param  和 type
     *     参数的格式如下:
     *     xiaoming/1
     *     其中chenchen是校验的数据
     *     Type为类型,可选参数1 username、2 phone、3 email
     * 返回值结果:SysResult对象
     *
     */
    @RequestMapping("/check/{param}/{type}")
    public JSONPObject checkUser(@PathVariable String param,@PathVariable Integer type,String callback){
        //根据客户端传来的param和type,去查询数据库,获取响应的结果
        Boolean flag = userService.checkUser(param,type);
        //int a = 1/0;  //由于不能保证服务器端会100%将业务处理成功,所以要完善全局异常处理类
        return new JSONPObject(callback,SysResult.success(flag));
    }

}

3.5 编辑jt-sso的UserService

public interface UserService {
    
    List<User> findAll();

    Boolean checkUser(String param, Integer type);
}

3.6 编辑jt-sso的UserServiceImpl

@Service
public class UserServiceImpl implements UserService{
    //将type: 1 username   2 phone  3 email  用Map的形式封装起来
    private static Map<Integer,String> paramMap = new HashMap<>();
    static{
        paramMap.put(1,"username");
        paramMap.put(2,"phone");
        paramMap.put(3,"email");
    }

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> findAll() {
        List<User> userList = userMapper.selectList(null);
        return userList;
    }

    /**
     * 校验数据
     * @param param 需要校验的数据
     * @param type  校验的类型  1 username   2 phone  3 email
     * @return
     */
    @Override
    public Boolean checkUser(String param, Integer type) {
        //通过Integer类型的type  获取它对应的名字(username phone email)
        String column = paramMap.get(type);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(column,param);  //注意 这里比对的是从map中得到的column和用户传来的param是否相同
        //如果根据传来的参数,从数据库中查出来的记录数>0,说明数据库中已经有这个用户的信息了,这个用户名就不能再注册了
        boolean flag = userMapper.selectCount(queryWrapper)>0?true:false;
        return flag;
    }
}

3.7 页面效果展现

在这里插入图片描述如果用户名可以注册,右边会显示绿色的对号。

3.8 修改全局异常处理类

之前客户端发的请求都是普通的ajax请求,请求的数据类型都是json。
这次的请求数据类型是JSONP,所以在全局异常处理类中要加入判断:
如果客户端是发的jsonp请求,那么返回的json结果要进行特殊的封装(用回调函数名包裹)
这个全局异常处理类在jt-common中
在这里插入图片描述

@RestControllerAdvice //作用:标识我是一个通知方法,并且只拦截Controller层的异常,(Service层和Mapper层的异常抛给Controller层就行了),并且返回JSON
public class SysResultException {

    //需要定义一个全局的方法,万一服务器干活fail了,返回指定的报错信息。
    //ExceptionHandler 配置异常的类型,这个例子中规定的是:遇到了运行时异常RuntimeException,就执行这个exception方法
    //JSONP请求的异常处理,返回的结果应该是这个样子 : callback({status:201,msg:"",data:""})
    //利用Request对象动态获取callback对应的回调函数名称,然后动态封装返回值

    @ExceptionHandler(RuntimeException.class)     //为了得到用户传递的callback对应的回调函数名具体是什么,要引入HttpServletRequest这个对象
    public Object exception(Exception e, HttpServletRequest request) {
        //在服务器控制台数据报错的原因,让程序员看的。
        e.printStackTrace();

        //从request的身上可以获得用户传过来的callback这个变量具体对应着什么样的回调函数名称
        String callback = request.getParameter("callback");
        if(!StringUtils.isEmpty(callback)){ //如果用户传过来的callback变量 不为空,说明它对应着方法名呢,也就说明此时用户发的是JSONP请求
            return new JSONPObject(callback,SysResult.fail());
        }
        return SysResult.fail();//SysResult.fail()会显示201,调用服务器失败。即告诉用户,我服务器这边出错了。
                                //但在页面上显示的信息是:新增商品失败!  是因为在item-add.jsp中第115行规定的。
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值