Golang与Angular 6的会话管理实现

Golang与Angular 6的会话管理实现 大家好,

我正在学习 Go 语言和 Angular 6。 我遇到的问题是,无法通过 Angular 6 的请求获取到我创建的会话。 我在 Go 中创建了一个简单的会话请求,但当我尝试从 Angular 再次拉取该会话时,会话值为空。

谢谢

4 回复

如果没有更多详细信息,很难回答您的问题。

  • 您是如何创建会话的?
  • 您如何在 Go 代码中存储它?
// 示例代码
func createSession() {
    // 会话创建逻辑
}

更多关于Golang与Angular 6的会话管理实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题已经解决了。 在我的 HTTP 请求中,只需要添加请求头即可。

  headerOption:RequestOptions;
  constructor() { 
    this.headerOption = new RequestOptions({
      headers: new Headers({ 
        'Content-Type':  'application/json'}),
        withCredentials: true
      });
  }

我参考了这个URL:https://github.com/gorilla/sessions

import (
		"net/http"
		"github.com/gorilla/sessions"
	)

	var store = sessions.NewCookieStore([]byte("something-very-secret"))

	func CreateSessionEndPoint(w http.ResponseWriter, req *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", allowedURL)
		session, _ := store.Get(req, "login")
		session.Values["userDetails"] = "Object values here...."
		session.Save(req, w)
	}

对于会话的检索,这是我的代码:

func CheckSessionEndPoint(w http.ResponseWriter, req *http.Request) {
    	w.Header().Set("Access-Control-Allow-Origin", allowedURL)
    	session, err := store.Get(req, "login")

    	if err != nil {
    		http.Error(w, err.Error(), http.StatusInternalServerError)
    		return
    	}

    	val := session.Values["userDetails"]
    	//var details = &UserDetails{}
    	details, _ := val.(*UserDetails)
    	fmt.Println(details) //从Angular调用时这里会显示null
    	json.NewEncoder(w).Encode(details)
    }

另外,Angular安装在我的Go项目外部。 我通过在每个函数端点添加"w.Header().Set(“Access-Control-Allow-Origin”, allowedURL)"来成功访问Go URL。

以下是我调用Go API的Angular代码:

import { Injectable } from '@angular/core';
import { Http, Request, RequestOptions, RequestMethod } from '@angular/http';
import { map, takeUntil, tap } from 'rxjs/operators';
import { UserLoginComponent } from '../../components/user-login/user-login.component';



@Injectable({
  providedIn: 'root'
})
export class AuthenticationService {

  

  constructor(private http:Http) { }

  login(userDetails:IUserDetails){


    let _body = JSON.stringify(userDetails);
    return this.http.post("http://localhost:8080/api/CreateSession",_body).pipe(map(res=>res.json()));
  }

  getSession(){
    var session = this.http.get("http://localhost:8080/api/checkSession").pipe(map(res=>res.json()));
    console.log(session.subscribe((posts)=>{
      console.log("get session",posts);
    }));
  }

}

export interface IUserDetails{
    ID:number,
    FirstName:string,
    LastName:string,
    Email:string,
    Password:string,
    BirthDate:Date,
    CreatedDate:Date
}

在 Go 和 Angular 6 中实现会话管理时,常见问题通常涉及跨域请求(CORS)或会话 cookie 处理。以下是完整的实现示例,确保会话在 Go 后端和 Angular 前端之间正确传递。

Go 后端实现

首先,使用 gorilla/sessions 包在 Go 中设置会话。确保配置 CORS 以允许 Angular 应用的请求,并正确处理会话 cookie。

  1. 安装依赖

    go get github.com/gorilla/sessions
    go get github.com/gorilla/mux
    
  2. Go 服务器代码

    package main
    
    import (
        "net/http"
        "github.com/gorilla/mux"
        "github.com/gorilla/sessions"
    )
    
    var store = sessions.NewCookieStore([]byte("your-secret-key"))
    
    func main() {
        r := mux.NewRouter()
    
        // 设置 CORS 中间件,允许 Angular 应用的源
        r.Use(func(next http.Handler) http.Handler {
            return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                w.Header().Set("Access-Control-Allow-Origin", "http://localhost:4200") // Angular 开发服务器地址
                w.Header().Set("Access-Control-Allow-Credentials", "true")
                w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
                w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
                if r.Method == "OPTIONS" {
                    w.WriteHeader(http.StatusOK)
                    return
                }
                next.ServeHTTP(w, r)
            })
        })
    
        // 创建会话的路由
        r.HandleFunc("/setsession", setSessionHandler).Methods("POST")
        r.HandleFunc("/getsession", getSessionHandler).Methods("GET")
    
        http.ListenAndServe(":8080", r)
    }
    
    func setSessionHandler(w http.ResponseWriter, r *http.Request) {
        session, _ := store.Get(r, "user-session")
        session.Values["username"] = "john_doe"
        session.Save(r, w)
        w.Write([]byte("Session set"))
    }
    
    func getSessionHandler(w http.ResponseWriter, r *http.Request) {
        session, _ := store.Get(r, "user-session")
        username, ok := session.Values["username"].(string)
        if !ok {
            http.Error(w, "Session not found", http.StatusUnauthorized)
            return
        }
        w.Write([]byte("Username: " + username))
    }
    

Angular 6 前端实现

在 Angular 中,使用 HttpClient 发送请求,并确保在请求中启用 withCredentials 以包含会话 cookie。

  1. 服务代码: 创建一个服务来处理 HTTP 请求。

    import { Injectable } from '[@angular](/user/angular)/core';
    import { HttpClient } from '[@angular](/user/angular)/common/http';
    
    [@Injectable](/user/Injectable)({
      providedIn: 'root'
    })
    export class SessionService {
      private baseUrl = 'http://localhost:8080';
    
      constructor(private http: HttpClient) { }
    
      setSession() {
        return this.http.post(`${this.baseUrl}/setsession`, {}, { withCredentials: true });
      }
    
      getSession() {
        return this.http.get(`${this.baseUrl}/getsession`, { withCredentials: true, responseType: 'text' });
      }
    }
    
  2. 组件代码: 在组件中调用服务方法。

    import { Component } from '[@angular](/user/angular)/core';
    import { SessionService } from './session.service';
    
    [@Component](/user/Component)({
      selector: 'app-root',
      template: `
        <button (click)="setSession()">Set Session</button>
        <button (click)="getSession()">Get Session</button>
        <p>{{ sessionData }}</p>
      `
    })
    export class AppComponent {
      sessionData: string;
    
      constructor(private sessionService: SessionService) {}
    
      setSession() {
        this.sessionService.setSession().subscribe(response => {
          console.log('Session set:', response);
        });
      }
    
      getSession() {
        this.sessionService.getSession().subscribe(
          response => {
            this.sessionData = response;
          },
          error => {
            this.sessionData = 'Error: ' + error.message;
          }
        );
      }
    }
    

关键点说明

  • CORS 配置:Go 后端必须设置 Access-Control-Allow-Origin 为 Angular 应用的 URL(例如 http://localhost:4200),并启用 Access-Control-Allow-Credentials: true
  • 会话 Cookie:在 Angular 的 HTTP 请求中设置 withCredentials: true,确保浏览器发送和接收 cookie。
  • 会话存储:使用 gorilla/sessionsCookieStore 在 Go 中管理会话,cookie 默认使用 HTTPOnly 标志,增强安全性。

运行 Go 服务器在端口 8080,Angular 应用在端口 4200。点击 “Set Session” 按钮设置会话,然后点击 “Get Session” 按钮检索会话数据。如果一切配置正确,Angular 将显示 “Username: john_doe”。

回到顶部