Hello. I'm new to Vapor 4 and Swift and I'm trying to figure out how to set a cookie to my response. I noticed on the vapor 4 docs that all they mention are session cookies, but I'm just trying to create a refresh token cookie with properties HttpOnly
Secure
and Max-Age
. When I looked at past versions, there's some mention of a class Cookie
but I don't see any references to that now nor am I sure what library they're using. Thank you!
Hi! You can create your own cookie and assign it to a Response
like so:
let cookie = HTTPCookies.Value(string: "some-value", expires: expiryDate, maxAge: 300, isSecure: false, isHTTPOnly: true, sameSite: HTTPCookies.SameSitePolicy.none)
response.cookies["cookie-name"] = cookie
This didn't work with me in Vapor 4.
What worked for me is to use the request.session
.
First register it in configure.swift
as
app.middleware.use(app.sessions.middleware)
It will automatically add a vapor-session
cookie for you.
Then later whenever you need the session id, use: req.session.id
You can also use req.session
to store any data related to the user session inside your web server.
Which bit didn't work? There's a difference between setting your own cookie and using sessions. One's server side and the other is client side. Is also depends on things like same site stuff etc, so the session cookie won't be available to you on a POST redirect but you can provide your own cookie that will be
Well, I found out that using request.session.id
didn't work with me either when using https 443 port (vapor 4 seems to have a bug in reading / setting session id when using https). But I figured out a work around by setting the cookie manually using the following:
let sessionID = UUID().uuidString
let response = req.redirect(to: "/")
let expiryDate = Date(timeIntervalSinceNow: TimeInterval(60 * 60 * 24 * 7)) // one week
let cookieExpiryDate = expiryDate.cookieFormattedString
let cookieValue = "sessionID=(sessionID); Expires=(cookieExpiryDate); Path=/; SameSite=Lax"
response.headers.add(name: "set-cookie", value: cookieValue)
return req.eventLoop.makeSucceededFuture(response)
public extension Date {
// Example: Thu, 03 Feb 2022 02:19:01 GMT var cookieFormattedString: String { let formatter = DateFormatter() formatter.timeZone = TimeZone(abbreviation: "GMT") formatter.dateFormat = "EEE, dd MMM YYYY HH:mm:ss zzz" return formatter.string(from: self) }
}