天天看點

springboot + jpa + jsonp跨域解決403問題前言jsonp原理具體執行個體Controller層代碼解決403問題的思路postman

前言

本例子是前後端分離,springboot版本是1.5.x ,資料層用的jpa,利用jsonp實作跨域,在使用jsonp時需要注意,jsonp隻能用get才能實作跨域,在使用jsonp的時候遇到了很多坑,和大家一起分享一下。

jsonp原理

JSONP是JSON with Padding的略稱。它是一個非官方的協定,它允許在伺服器端內建Script tags傳回至用戶端,通過javascript callback的形式實作跨域通路(這僅僅是JSONP簡單的實作形式)。–來源百度

package com.example.student.config;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;


/**
 * jsonp實作跨域
 */
@ControllerAdvice(basePackages = {"com.sinoyd.controller"})
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {

    public JsonpAdvice() {
        super("callback", "jsonp");
    }
}
           

具體執行個體Controller層代碼

/**
     * 使用jsonp形式登入
     *
     * @param uid
     * @param pid
     * @param response
     * @return
     */
    @RequestMapping(value = "/testJsonp/login", produces = MediaType.APPLICATION_JSON_VALUE)
    public Object login(@RequestParam("userName") String userName, @RequestParam("password") String passWord, HttpServletResponse response) {
        try {
            Validator validator = Validator.create()
                    .notEmpty("使用者名", userName)
                    .notEmpty("密碼", passWord);
            if (!validator.valid()) {
                response.setStatus(ResStatus.BAD_REQUEST.getCode());
                return ResEntity.failed(new ResException(validator.getMessage()), ResStatus.BAD_REQUEST);
            }
            // 加密方式--這個可以去掉
            String passWord1= EncryptUtil.decrypt(passWord);
            String userName1= EncryptUtil.decrypt(userName);
            Helpers.requireNonNull("使用者名或密碼錯誤", passWord1, userName1);
            User user = new User();
            user.setUserName(userName1.trim());
            user.setPassword(passWord1.trim());
            return ResEntity.success(authService.login(user, response, true));
        } catch (Exception e) {
            response.setStatus(ResStatus.FAILED.getCode());
            return ResEntity.failed(e);
        }
    }
           

== @RequestMapping(value = “/testJsonp/login”, produces = MediaType.APPLICATION_JSON_VALUE)==

這個一定要加上,使用jsonp前端一定要使用get方式

解決403問題的思路

403–伺服器拒絕通路,一般都是沒有權限,解決思路是:1.jsonp的調用方式 --get 2.使用jsonp後,前端無法擷取token,這個時候必須把token放在傳回值中。如果有什麼不懂的可以随時聯系我。3.如果使用了權限架構的時候記得把這個接口的路徑攔截放行。

@Configuration
@EnableWebSecurity//(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    private final RedisTemplate redisTemplate;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    public WebSecurityConfig(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    // 設定 HTTP 驗證規則
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers("/public/**", "/html/**", "/static/**", "/vendor/**", "/**/*.js", "/fonts/**", "/**/*.css", "/index.html", "/*.js", "/api/static/files/**").permitAll()
                .antMatchers(HttpMethod.POST, "/api/auth/**").denyAll()
                .antMatchers("/api/qyt/report/**").permitAll()
                .antMatchers(HttpMethod.GET, "/api/auth/testJsonp/login").permitAll() //jsonp跨域路徑放行
                .antMatchers("/api/qyt/notice/**").permitAll()
                .antMatchers("/api/qyt/attach/**").permitAll()
                .antMatchers("/api/qyt/job-test/**").permitAll()
                .anyRequest().authenticated() // 所有請求需要身份認證
                .and().headers().frameOptions().disable()// 禁用x-frame 、
                .and()
                .addFilter(new JwtTokenFilter(authenticationManager(), jwtTokenUtil)); //自定義攔截器
    }
}
           

postman

測試成功示例:

springboot + jpa + jsonp跨域解決403問題前言jsonp原理具體執行個體Controller層代碼解決403問題的思路postman

繼續閱讀