springboot第85集:分布式拒绝服务攻击,初级架构师,数据库表

80 阅读6分钟
@Data // 自动生成getter和setter方法
@Builder // 自动生成Builder模式的方法
public class MongoResultSet<T> {
    // 总数
    Long total;
    // 结果列表
    List<T> result;
}

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

{
	code:0,
	msg:"success",
	data:数据
}

封装一个类,例如:

@Data
public class Result implements Serializable {
    private Integer code;
    private String msg;
    private Object data;
    private Result(){}
    public static Result success(Object data){
        Result result = new Result();
        result.setCode(ResultCode.SUCCESS.code());
        result.setMsg(ResultCode.SUCCESS.msg());
        result.setData(data);
        return result;
    }
    public static Result failure(String message){
        Result result = new Result();
        result.setCode(ResultCode.FAILURE.code());
        result.setMsg(message);
        result.setData(null);
        return result;
    }
}

还会写一个枚举类作为code和msg

public enum ResultCode {
    SUCCESS(0,"成功"),
    FAILURE(-1,"失败");

    private Integer code;
    private String msg;

    ResultCode(Integer code, String msg){
        this.code = code;
        this.msg = msg;
    }
    public Integer code(){
        return this.code;
    }
    public String msg(){
        return this.msg;
    }
}

利用springboot的全局响应拦截

创建一个类,打上注解@ControllerAdvice,再实现ResponseBodyAdvice<Object>接口

必须在里面重写两个方法,一个boolean supports()方法,一个Object beforeBodyWrite()方法

beforeBodyWrite就可以重写响应结果,而supports方法返回的boolean值决定是否执行beforeBodyWrite方法

如果一味的将supports方法返回true,那么说明每一个响应都会返回统一的格式,但如果我有一个请求想返回一个文件流呢

基于以上想法,暂且想到的解决思路:

自定义一个注解,将注解打在请求的方法上,创建一个全局拦截器,拦截请求,如果请求的方法上发现有我们自定义的注解,那么我们在request请求域中添加一个属性(标识),然后再全局响应拦截中的supports()方法中,判断请求域中是否有之前添加的标识,如果有,则返回true,没有就返回false。返回true就表示执行beforeBodyWrite()方法,就可以重写响应结果

实战:

1、创建一个自定义注解:

@Target(ElementType.METHOD) // 该注解可以使用在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResultApi {
}

2、创建一个拦截器

@Component
public class ResultInterceptor implements HandlerInterceptor {
    // 标记
    public static final String RESPONSE_RESULT = "response_flag";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            // 获取方法名
            Method method = handlerMethod.getMethod();
            // 如果方法被ResultApi注解修饰
            if(method.isAnnotationPresent(ResultApi.class)){
                request.setAttribute(RESPONSE_RESULT,method.getAnnotation(ResultApi.class));
            }
        }
        return true;
    }
}

3、使拦截器生效,并拦截所有路径

@Configuration
public class MyWebConfig implements WebMvcConfigurer {
    /**
     * 拦截全部
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new ResultInterceptor()).addPathPatterns("/**");
    }
}

常用注解:

注解作用使用位置
@Api表示对类的说明常用参数类上面
@ApiOperation说明方法的用途、作用方法上面
@ApiModel表示一个返回响应数据的信息响应类
@ApiModelProperty描述响应类的属性属性
@ApiIgnore忽略某个字段使之不显示在文档中属性

1、前后端分离中,后端都会统一返回类似这样的结构

{
	code0,
	msg:‘success’,
	data:[		{id:1,name:'aa',age:18}	]
}

如果每次都自己去new,或者调用静态方法Result.success()。是不是太麻烦了,于是写了一个自定义注解,只要在方法上添加注解,即可自动返回上述结构

类似这样@ResultApi

    @ResultApi
    @ApiOperation("查询底部设置号码列表")
    @PreAuthorize("hasAuthority('sys:foot:pageList')")
    @PostMapping("/pageList")
    public PageVo<SysPhone> pageList(@RequestBody SysPhone sysPhone){
        return sysFootService.pageList(sysPhone);
    }

oauth,单点登录 主攻java和前端了 python 视频服务,MinIO

微信扫码登录

安全框架SpringSecurity

中英文切换导入

logo图切换svg,保证不失真效果

使用mixin混入达到配置项fullpage的复用效果

微信扫码登录

1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;
3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

一共是两种方式,但两种方式的原理基本相同,第一种是在原来的网页打开一个新的标签页,标签页中涵盖微信提供的二维码。

第一种方式需要后端提供一个微信二维码的地址,返回给前端,前端调用window.open打开一个新的标签页

第二种是在自己的网页中内嵌微信提供的二维码。将使用微信提供的js库,自动获取微信的扫描二维码

将页面引入 res.wx.qq.com/connect/zh_… 这个js,由微信官方提供

在需要使用微信登录的地方实例以下JS对象:

var obj = new WxLogin({
        self_redirect:true,
        id:"login_container", 
        appid: "", 
        scope: "", 
        redirect_uri: "",
        state: "",
        style: "",
        href: ""
 });
// 举个例子
var obj = new WxLogin({           
                              self_redirect:false,
                              id:"wxPng", 
                              appid: "xx", 
                              scope: "snsapi_login", 
                              redirect_uri: encodeURIComponent("http://ip.cn"),
                              state: "",
                              style: "black",
                              href: "data:text/css;base64,LmltcG93ZXJCb3ggLnRpdGxlewogIGRpc3BsYXk6IG5vbmU7Cn0KCi5pbXBvd2VyQm94IC53YWl0aW5nIC5pbmZvIHsKICBkaXNwbGF5OiBub25lOwp9CgouaW1wb3dlckJveCAud2FpdGluZyAud3JwX2NvZGUgewogIG1hcmdpbjogMCBhdXRvOyAKICB3aWR0aDogMjAwcHg7CiAgYm9yZGVyOiBub25lOwp9CgouaW1wb3dlckJveCAud2FpdGluZyAucXJjb2RlIHsKICBib3JkZXI6IDA7CiAgd2lkdGg6IDEwMCU7Cn0="
                            });

参数 是否必须 说明

self_redirect 否 true:手机点击确认登录后可以在 iframe 内跳转到 redirect_uri,false:手机点击确认登录后可以在 top window 跳转到 redirect_uri。默认为 false。

id 是 第三方页面显示二维码的容器id

appid 是 应用唯一标识,在微信开放平台提交应用审核通过后获得

scope 是 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 redirect_uri 是 重定向地址,需要进行UrlEncode

state 否 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

style 否 提供"black"、"white"可选,默认为黑色文字描述。详见文档底部FAQ

href 否 自定义样式链接,第三方可根据实际需求覆盖默认样式。

我们这里需要自定义css,可以使用href属性字段,将css发布到公网上,或者将css写好之后,进行base编码之后。直接赋值。例如:

// 自定义样式
.impowerBox .title {
 display: none;
}
.impowerBox .status.status_browser {
 display: none;
}
.impowerBox .qrcode {
 border: none;
 width: 200px;
 height: 200px;
}
.impowerBox .status{
 display: none
}

进行base64编码:

href必须使用 text/css模式,生成的base64添加到'data:text/css;base64,'后面就可以了

@Slf4j
@Component
public class InitDataSource {
    @Autowired
    private InitMapper initMapper;

    @PostConstruct
    public void init(){
        log.info("初始化hikari连接池");
        // 初始化hikari连接池
        initMapper.Init();
    }
}

在用户扫完码确认授权后,页面会跳转到你之前设置的回调地址,如果在本地开发的话 ,可以改host文件,将127.0.0.1指向bugtracker.itsource.cn地址

他会携带一个code和state参数,这个时候你在这个页面初始化时,检测地址url是否有code和state参数,如果有,那就往后台发送请求,后台会做两件事

1、通过code参数加上AppID和AppSecret等,通过API换取access_token;

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

返回结果:

{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

openid就是微信用户的唯一标识

通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

PV和UV

pv:pageViews,页面访问次数,同一个电脑访问次数可以叠加

uv:uniqueVisitor,独立访问客户,同一个电脑访问次数不算叠加

加群联系作者vx:xiaoda0423

仓库地址:github.com/webVueBlog/…