搜索

首页  >  问答  >  正文

angular.js - 跨域造成session丢失

我部署了一个angular工程 基于nodejs HTTP-server启动的,登陆url: http://localhost:9000/#/login
java工程项目 登陆url: http://localhost:8060/login
而我现在想在angular工程上完全只是调用java工程项目接口,而java项目现在准备纯碎只是为angular工程提供返回的json数据而已
在过程中出现跨域问题,我就在java工程上统一设置拦截器 在有新请求调用时都设置响应头:
response.setHeader("Access-Control-Allow-Origin" , "*" ); 即可解决跨域问题;
但是session丢失问题没解决
就是说我在angular项目调用登陆接口登陆,服务器端会创建一个session,并返回用户信息及权限信息等json数据 ,还有返回一个jsessionid到客户端;
如图所示:

登陆成功跳转至http://localhost:9000/#/home

但是我在首页点击左侧菜单执行java工程的其他接口时,比如说查询用户列表接口,它又被拦截掉,返回login接口,因为由请求头中找不到对应的jsessionid,相当于当前用户还处于未登陆状态
原理是:每次调用接口即发出新请求首先都会判断url上是否携带jsession,如果没有,则判断请求头的cookies中有jsession,如果已存在,则会传到后台,后台通过jsession获取对应session;可是如果jsession不存在或者通过jsession获取不到对应session的话,则会从新创建一个session


我想问一下就是怎么才能避免跨域调用接口导致session丢失呢?

世界只因有你世界只因有你2744 天前767

全部回复(4)我来回复

  • 迷茫

    迷茫2017-05-15 16:54:59

    所以到现在都没有解决方案么。。

    update
    我解决了。后端是Java springboot,前端是angular,跨域json通信。
    cors方式,配置一个corsfilter,代码如下:

    package xxxxxx.component;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * Created by skyADMIN on 16/7/4.
     */
    @Component
    public class CORSFilter implements Filter {
    
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
    
            response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
            response.setHeader("Access-Control-Allow-Credentials","true"); //是否支持cookie跨域
            chain.doFilter(req, res);
        }
    
        public void init(FilterConfig filterConfig) {}
    
        public void destroy() {}
    
    }

    这个配置在不少地方应该都能找到,不同的主要是两点:
    1。response.setHeader("Access-Control-Allow-Credentials","true"); //是否支持cookie跨域
    2。response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));

    首先,配置了allow-credentials之后,如果allow-origin设为*,跨域时会报错说因为允许credentials,origin不能设为通配*,那所以设为简单的某个domain也是可以的,这种写法应该就是达到了任意domain都可以的效果吧。

    然后angular部分也要设定个东西,举个栗子~

    angular.module('frontendApp')
      .controller('MainCtrl', function ($scope, $http, $location) {
        var action = 'islogin';
        $http.get(apiUrl + action, {withCredentials: true}).then(function (response) {
          console.log(response);
          if (response.data === 0) {
            $location.url('login');
          }
        })
      });

    恩就是这个$http.get(url, {withCredentials: true})。
    ok就酱。

    回复
    0
  • 高洛峰

    高洛峰2017-05-15 16:54:59

    Access-Control-Allow-Origin设置为*只是用来解决post请求跨域的问题的,cookie是没法跨域的,或者说只能跨2级域名,每个cookie都会有对应的域,写的时候可以指定为允许同一个1级域名下的所有2级域名访问,比如sf的

    回复
    0
  • ringa_lee

    ringa_lee2017-05-15 16:54:59

    既然是ng工程,你的载入页面应该只有一个,让java这边给你做一个入口,返回这个页面就好了。

    引出的问题可能是你的angular模板如果都需要异步载入,也会跨域,一个方案是像你上面那样加上origin,另一个是直接将模板也打包成脚本直接加入进去

    回复
    0
  • 黄舟

    黄舟2017-05-15 16:54:59

    有解决方案了吗?

    回复
    0
  • 取消回复