【问题标题】:Session HTTP - Spring and Angular 2会话 HTTP - Spring 和 Angular 2
【发布时间】:2017-05-04 04:13:18
【问题描述】:

向我的 Spring Boot 应用程序添加身份验证功能时遇到问题。 我已经实现了如下的会话模式。

AdminSession.java

@Component
@Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class AdminSession {
private final String id = UUID.randomUUID().toString();
private Admin admin;

public String getId() {
    return id;
}

public Admin getAdmin() {
    return admin;
}

public void setAdmin(Admin admin) {
    this.admin = admin;
}
}

AdminController.java

@RequestMapping("/admin")
@CrossOrigin
@RestController
public class AdminController extends RestAbstractController<Admin, AdminService>{
@Autowired
private AdminService adminService;
@Autowired
private AdminSession adminSession;


@RequestMapping(value="/auth",method=RequestMethod.POST)
public ResponseEntity<Admin> auth(
@RequestParam("pseudo") String pseudo, 
@RequestParam("password") String password,
){
Admin a = this.adminService.auth(pseudo, password);
if(a instanceof Admin) {
this.adminSession.setAdmin(a);
System.out.println("[DEBUG] Login "+this.adminSession.getAdmin());
this.displaySessionInfo();
}else System.err.println("[ERROR] a is not Admin instance");
return new ResponseEntity<Admin>(a,HttpStatus.ACCEPTED);
}

public Admin add(@RequestBody Admin admin){
if(!this.adminService.exist(admin.getPseudo())){
return super.add(admin);
}else return new Admin();

}

@RequestMapping("/isAuth")
public Admin isAuth(){

this.displaySessionInfo();
return this.adminSession.getAdmin();

}

private void displaySessionInfo(){
System.out.println("[DEBUG] Session info : "+this.adminSession.getId()+" "+this.adminSession.getAdmin()+" "+this.adminSession.toString());
}


}

问题是当我尝试连接到 Angular 端时,Spring 会在会话中正确保存用户。但是当我登录后尝试访问 URL '/admin/isAuth' 时,会话就不一样了。

控制台日志

2017-05-03 19:08:52.258  INFO 756 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 124 ms
# FIRST LOGIN
[DEBUG] Client connexion : 127.0.0.1 on /admin/auth
[DEBUG] Login root 
[DEBUG] Session info : 31e7a837-7b0e-4bcc-83a2-b5297a76d2e0 root fr.-----.session.AdminSession@6039cb34
# LOGIN SUCCESSFUL
# CHECK IS LOGIN
[DEBUG] Client connexion : 127.0.0.1 on /admin/isAuth
[DEBUG] Session info : f83ba190-0faa-480b-be1d-4b2745d4a168 null fr.-----.session.AdminSession@6052863f

侧角 2

Admin.service.ts

auth(pseudo:string,password:string):Observable<Admin>{
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded;' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.provider.getURL()+"/admin/auth","pseudo="+pseudo+"&password="+password,options)
.map(this.extractData);
}

Login.component.ts

submit(){
    this.process=true;
    this.adminService.auth(this.pseudo,this.password).subscribe(t=>{
      this.adminService.isAuth();
      this.process=false;
      this.adminService.isAuthentified = true;
      this.provider.tokenSession = t;
      this.adminService.isAuth().subscribe(t=>console.log("Test login"));
      this.router.navigate(['/']);
    },err=>console.error(err));
  }

为什么我丢失了我的 http 会话?

感谢您的帮助。

【问题讨论】:

  • 你是先用浏览器还是其他HTTP客户端测试的?
  • 我用同样的http浏览器,同样的onglet,不同的,...
  • 你能告诉我你是如何注入 this.adminService 的吗?
  • 我已经在下面添加了代码。
  • 一切正常。需要从初级诊断开始。如何使用 http.get 针对普通 API 发送多个测试请求。然后检查会话的行为。

标签: java spring angular session spring-boot


【解决方案1】:

我已经确定了问题所在。我支持 Angular 2。 对于eatch 请求,标头需要'withCredentials';

export class MyService {
  private httpGetOptions : RequestOptions = new RequestOptions({ withCredentials: true });

  getSomeone (): Observable<any> {
    return this.http.get(url,this.httpGetOptions);
  }
}

【讨论】:

    【解决方案2】:

    AdminService.java

    @Service
    public class AdminService extends RestAbstractService<Admin, AdminRepository>{
    
        @Autowired
        private AdminRepository adminRepository;
    
        public Admin auth(String pseudo, String password, AdminSession adminSession){
            Admin a = this.adminRepository.findAdminByPseudo(pseudo);
            if(a instanceof Admin)
                if(a.getPassword().equals(password)) {
                    adminSession.setAdmin(a);
                    a.setPassword(null);
                    return a;
                }
                else return null;
            else if(pseudo.equals("root") & Admin.root.getPassword().equals(password))
                return Admin.root;
            else return null;
        }
    
        public boolean exist(String pseudo){
            return this.adminRepository.findAdminByPseudo(pseudo) instanceof Admin;
        }
    
        public boolean isAuth(AdminSession adminSession){
            return adminSession.getAdmin() instanceof Admin;
        }
    
    
        public void logout(AdminSession adminSession){
            adminSession.setAdmin(null);
        }
    }
    

    Admin.service.ts

    @Injectable()
    export class AdminService {
      isAuthentified:boolean;
      constructor(private provider :ProviderService, private http:Http) { }
    
      auth(pseudo:string,password:string):Observable<Admin>{
        let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded;' });
        let options = new RequestOptions({ headers: headers });
        return this.http.post(this.provider.getURL()+"/admin/auth","pseudo="+pseudo+"&password="+password,options)
          .map(this.extractData);
      }
    
      isAuth():Observable<boolean>{    
        let headers = new Headers({ 'Content-Type': 'application/json;', 'token': this.provider.tokenSession.token});
        let options = new RequestOptions({ headers: headers });
        return this.http.get(this.provider.getURL()+"/admin/isAuth",)
            .map(this.extractBoolean);
      }
    
      private extractData(res: Response) {
        let body = res.json();
        return body;
      }
    
      private extractBoolean(res:Response){
        this.isAuthentified = res.text() === 'true';
        return this.isAuthentified;
      }
    
    
      private handleError (error: Response | any) {
        let errMsg: string;
        if (error instanceof Response) {
          const body = error.json() || '';
          const err = body.error || JSON.stringify(body);
          errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
          errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
      }
    
    }
    

    在“providerService”中,我可以通过 IP 访问 Web 服务 Spring。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-04
      • 2013-12-01
      • 2019-08-08
      • 2012-12-07
      • 2023-04-04
      • 2017-06-25
      • 2015-05-07
      • 2013-04-27
      相关资源
      最近更新 更多