I have the users landing on a login page. When they successfully login, this should then redirect them to the users page. However this is not happening and am unsure why. It seems as though the ajax call is going into the error for some reason (Am unsure as to why). I can see though when I log the response that the new page has come through in the response text.
login method that should redirect user:
// this map stores the users sessions. For larger scale applications, you can use a database or cache for this purpose
var sessions = map[string]session{}
// each session contains the username of the user and the time at which it expires
type session struct {
username string
expiry time.Time
}
// we'll use this method later to determine if the session has expired
func (s session) isExpired() bool {
return s.expiry.Before(time.Now())
}
// Credentials Create a struct that models the structure of a user in the request body
type Credentials struct {
Password string `json:"password"`
Username string `json:"username"`
}
func login(w http.ResponseWriter, r *http.Request) {
log.Println("login started")
var creds Credentials
// Get the JSON body and decode into credentials
if err := json.NewDecoder(r.Body).Decode(&creds); err != nil {
// If the structure of the body is wrong, return an HTTP error
log.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}
// Get the expected password from our in memory map
expectedPassword, ok := "test", true
// If a password exists for the given user
// AND, if it is the same as the password we received, then we can move ahead
// if NOT, then we return an "Unauthorized" status
if !ok || expectedPassword != creds.Password {
log.Println("bad password")
w.WriteHeader(http.StatusUnauthorized)
return
}
// Create a new random session token
// we use the "github.com/google/uuid" library to generate UUIDs
sessionToken := uuid.NewString()
expiresAt := time.Now().Add(120 * time.Second)
// Set the token in the session map, along with the session information
sessions[sessionToken] = session{
username: creds.Username,
expiry: expiresAt,
}
// Finally, we set the client cookie for "session_token" as the session token we just generated
// we also set an expiry time of 120 seconds
http.SetCookie(w, &http.Cookie{
Name: "session_token",
Value: sessionToken,
Expires: expiresAt,
})
log.Println("login success")
http.Redirect(w, r, "/users", http.StatusFound)
}
Ajax call:
function handleSubmit(evt) {
evt.preventDefault();
let form = evt.target;
let data = new FormData(form);
if (data.get("username") != null && data.get("username") != "") {
$.ajax({
url: '/login',
method: 'post',
data: JSON.stringify(Object.fromEntries(data)),
dataType: 'json',
success: (resp) => {
if (resp.redirect) {
// resp.redirect contains the string URL to redirect to
window.location.redirect = resp.redirect;
}
},
error: (resp) => {
console.log("An error occurred. Please try again");
console.log(resp)
}
});
}
return false
}
CodePudding user response:
so to fix ur issue u should modify a little bit your server code
func login(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
log.Println("login started")
var creds Credentials
// Get the JSON body and decode into credentials
if err := json.NewDecoder(r.Body).Decode(&creds); err != nil {
// If the structure of the body is wrong, return an HTTP error
log.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}
// Get the expected password from our in memory map
expectedPassword, ok := "test", true
// If a password exists for the given user
// AND, if it is the same as the password we received, then we can move ahead
// if NOT, then we return an "Unauthorized" status
if !ok || expectedPassword != creds.Password {
log.Println("bad password")
w.WriteHeader(http.StatusUnauthorized)
return
}
// Create a new random session token
// we use the "github.com/google/uuid" library to generate UUIDs
sessionToken := uuid.NewString()
expiresAt := time.Now().Add(120 * time.Second)
// Set the token in the session map, along with the session information
sessions[sessionToken] = session{
username: creds.Username,
expiry: expiresAt,
}
// Finally, we set the client cookie for "session_token" as the session token we just generated
// we also set an expiry time of 120 seconds
http.SetCookie(w, &http.Cookie{
Name: "session_token",
Value: sessionToken,
Expires: expiresAt,
})
log.Println("login success")
by, _ := json.Marshal(map[string]interface{}{
"to": "http://localhost:8085/users",
})
w.Write(by)
}
i used json response instead of http.redirect. Back to your ajax call, i change again the datatype to json because our server now send json. change the if condition from resp.redirect to resp.to, and use window.location.href instead of windows.location.redirect.
function handleSubmit(evt) {
evt.preventDefault();
let form = evt.target;
let data = new FormData(form);
if (data.get("username") != null && data.get("username") != "") {
$.ajax({
url: 'http://localhost:8085/login',
method: 'post',
data: JSON.stringify(Object.fromEntries(data)),
dataType: 'json',
success: (resp) => {
if (resp.to) {
window.location.href = resp.to;
}
},
error: (resp) => {
console.log("An error occurred. Please try again");
console.log(resp)
}
});
}
return false
}