Je travaille sur une application de connexion. Après la connexion réussie, la réponse revient avec les données du cookie.
Comment puis-je utiliser/sauvegarder ces données pour mes futures demandes?
Pour commencer, j'essaie de le sauvegarder dans NSHTTPCookieStorage
. Mais cela ne fonctionne pas non plus .
Méthode de connexion (partielle):
let task = session.dataTaskWithRequest(request) { (data, responseData, error) -> Void in
if let response = responseData as? NSHTTPURLResponse {
statusCode = response.statusCode
print("Response code: \(statusCode)")
}
var json: NSDictionary?
do {
json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
} catch {
print(error)
err = error
}
if(statusCode != 200) {
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: '\(jsonStr)'")
}
else {
print("Everything Looks good: \(responseData)")
self.setCookies(responseData!)
self.shouldPerformSegueWithIdentifier("showHomeController", sender: self)
}
}
task?.resume()
Enregistrer la méthode du cookie
private func setCookies(response: NSURLResponse) {
if let httpResponse = response as? NSHTTPURLResponse {
let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(httpResponse.allHeaderFields, forURL: response.URL!) as! [NSHTTPCookie]
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookies(cookies, forURL: response.URL!, mainDocumentURL: nil)
for cookie in cookies {
var cookieProperties = [String: AnyObject]()
cookieProperties[NSHTTPCookieName] = cookie.name
cookieProperties[NSHTTPCookieValue] = cookie.value()
cookieProperties[NSHTTPCookieDomain] = cookie.domain
cookieProperties[NSHTTPCookiePath] = cookie.path
cookieProperties[NSHTTPCookieVersion] = NSNumber(integer: cookie.version)
cookieProperties[NSHTTPCookieExpires] = NSDate().dateByAddingTimeInterval(31536000)
let newCookie = NSHTTPCookie(properties: cookieProperties)
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(newCookie!)
println("name: \(cookie.name) value: \(cookie.value())")
}
}
}
Erreur:
Cannot invoke 'cookiesWithResponseHeaderFields' with an argument list of type '([NSObject : AnyObject], forURL: NSURL)'
Si vous vous rendez compte de l'utilisation du cookie, le serveur doit envoyer l'en-tête Set-Cookie
en réponse à la demande du client. Inspectez simplement l'en-tête en réponse et vous verrez le champ d'en-tête Set-Cookie
avec le cookie.
_ { https://en.wikipedia.org/wiki/HTTP_cookie#Setting_a_cookie } _
Si vous utilisez URLSession avec la variable par défaut ou l'arrière-plan URLSessionConfiguration
, vous ne devez apporter aucune modification pour enregistrer le cookie. Si vous regardez la documentation par défaut URLSessionConfiguration
, qui la décrit comme ceci,
La configuration de session par défaut utilise un cache persistant basé sur disque (sauf lorsque le résultat est téléchargé dans un fichier) et stocke informations d’identité dans le trousseau de l’utilisateur. Il stocke également les cookies (par Default) dans le même magasin de cookies partagé que NSURLConnection et NSURLDownload classes.
Vous pouvez également en savoir plus à ce sujet dans la documentation URLSessionConfiguration
de la propriété httpCookieStorage
ici .
Voici un petit extrait de code que je vais utiliser plus tard pour tester le stockage des cookies.
let sessionConfiguration = URLSessionConfiguration.ephemeral
sessionConfiguration.httpCookieAcceptPolicy = .never
let customSession = URLSession(configuration: sessionConfiguration)
enum Result {
case success(HTTPURLResponse, Data)
case failure(Error)
}
func readCookie(forURL url: URL) -> [HTTPCookie] {
let cookieStorage = HTTPCookieStorage.shared
let cookies = cookieStorage.cookies(for: url) ?? []
return cookies
}
func deleteCookies(forURL url: URL) {
let cookieStorage = HTTPCookieStorage.shared
for cookie in readCookie(forURL: url) {
cookieStorage.deleteCookie(cookie)
}
}
func storeCookies(_ cookies: [HTTPCookie], forURL url: URL) {
let cookieStorage = HTTPCookieStorage.shared
cookieStorage.setCookies(cookies,
for: url,
mainDocumentURL: nil)
}
func executeURLRequest(url: URL, inSession session: URLSession = .shared, completion: @escaping (Result) -> Void) {
let task = session.dataTask(with: url) { data, response, error in
if let response = response as? HTTPURLResponse,
let data = data {
completion(.success(response, data))
return
}
if let error = error {
completion(.failure(error))
return
}
let error = NSError(domain: "com.cookiesetting.test", code: 101, userInfo: [NSLocalizedDescriptionKey: "Unknown error occurred"])
completion(.failure(error))
}
task.resume()
}
Avec l'extrait de code ci-dessus, nous testons d'abord que la session par défaut enregistre le cookie.
var cookies = readCookie(forURL: googleURL)
print("Cookies before request: ", cookies)
executeURLRequest(url: googleURL) { result in
if case .success (let data) = result {
cookies = readCookie(forURL: googleURL)
print("Cookies after request: ", cookies)
deleteCookies(forURL: googleURL)
cookies = readCookie(forURL: googleURL)
print("Cookies after deletion: ", cookies)
}
}
Et voici ce que nous obtenons,
Cookies before request: []
Cookies after request: [<NSHTTPCookie
version:0
name:1P_JAR
value:2018-09-26-15
expiresDate:'2018-10-26 15:39:46 +0000'
created:'2018-09-26 15:39:46 +0000'
sessionOnly:FALSE
domain:.google.com
partition:none
sameSite:none
path:/
isSecure:FALSE
path:"/" isSecure:FALSE>, <NSHTTPCookie
version:0
name:NID
value:139=E3g4bKNRGcYoeFuaECpfsx_Efp64xONmVwcJS7f7PuZe8LayS5ZkGuz3f7z6eq7zoBm2z-opTvzX8YPzn8v1ebjH6iyt5-6yDYm9RE6XhXwHCZWs98_j7nb11u2EPnHI
expiresDate:'2019-03-28 15:39:46 +0000'
created:'2018-09-26 15:39:46 +0000'
sessionOnly:FALSE
domain:.google.com
partition:none
sameSite:none
path:/
isSecure:FALSE
isHTTPOnly: YES
path:"/" isSecure:FALSE isHTTPOnly: YES>]
Cookies after deletion: []
URLSessionConfiguration
a également une propriété httpCookieAcceptPolicy
, qui cite ce qui suit:
Cette propriété détermine la politique d'acceptation des cookies pour toutes les tâches de sessions basées sur cette configuration.
La valeur par défaut est HTTPCookie.AcceptPolicy.onlyFromMainDocumentDomain. Vous pouvez le changer à l'une des constantes définies dans HTTPCookie.AcceptPolicy type énuméré.
Si vous souhaitez davantage de contrôle direct sur les cookies acceptés, définissez cette valeur à HTTPCookie.AcceptPolicy.never, puis utilisez le fichier allHeaderFields et les cookies (withResponseHeaderFields: for :) méthodes to extraire les cookies de l'objet de réponse URL vous-même.
Ainsi, si vous souhaitez manipuler le cookie vous-même, vous pouvez définir la variable httpCookieAcceptPolicy
sur never
.
Le code suivant montre, cookie non enregistré lors de l'utilisation de httpCookieAcceptPolicy to never,
var cookies = readCookie(forURL: googleURL)
print("Cookies before request: ", cookies)
executeURLRequest(url: googleURL, inSession: customSession) { result in
if case .success (let data) = result {
cookies = readCookie(forURL: googleURL)
print("Cookies after request: ", cookies)
}
}
Qui enregistre les suivants:
Cookies before request: []
Cookies after request: []
Vous pouvez constater qu'en utilisant .never pour httpCookieStoragePolicy, le système ne stocke pas de cookie dans un stockage de cookie partagé.
Vous pouvez également stocker le cookie vous-même, qui ressemblerait à ceci,
Stocker le cookie par nous-mêmes
deleteCookies(forURL: googleURL)
var cookies = readCookie(forURL: googleURL)
print("Cookies before request: ", cookies)
executeURLRequest(url: googleURL, inSession: customSession) { result in
if case let .success (response, data) = result {
guard let cookiesResponseHeader = response.allHeaderFields["Set-Cookie"] else {
return
}
cookies = readCookie(forURL: googleURL)
print("Cookies after request: ", cookies)
let responseCookies = HTTPCookie.cookies(withResponseHeaderFields: response.allHeaderFields as! [String: String], for: googleURL)
storeCookies(responseCookies, forURL: googleURL)
cookies = readCookie(forURL: googleURL)
print("Cookies after storing: ", cookies)
}
}
Et, voici ce que le code ci-dessus affiche sur la console,
Cookies before request: []
Cookies after request: []
Cookies after storing: [<NSHTTPCookie
version:0
name:1P_JAR
value:2018-09-26-18
expiresDate:'2018-10-26 18:35:23 +0000'
created:'2018-09-26 18:35:23 +0000'
sessionOnly:FALSE
domain:.google.com
partition:none
sameSite:none
path:/
isSecure:FALSE
path:"/" isSecure:FALSE>, <NSHTTPCookie
version:0
name:NID
value:139=D7GTUazWfeaB5Bcu1wN5I_Il2k6xALNiRZDX_DN9totQbnrP31gE0GzlsjCHDISUv8ulPq9G8Yu1p-GsZcVRw2fnrBROih-vtAVBic5UXFKUkG_ZbFQYKFprr4MPHDGS
expiresDate:'2019-03-28 18:35:23 +0000'
created:'2018-09-26 18:35:23 +0000'
sessionOnly:FALSE
domain:.google.com
partition:none
sameSite:none
path:/
isSecure:FALSE
isHTTPOnly: YES
path:"/" isSecure:FALSE isHTTPOnly: YES>]
Le code ci-dessus utilise .never
HTTPCookieAcceptPolicy pour URLSessionConfiguration mais nous créons un cookie à partir de la réponse et le stockons nous-mêmes dans le magasin de cookies.
class func cookiesWithResponseHeaderFields (_ headerFields: [String: String], URL forURL: NSURL) -> [NSHTTPCookie]
Notez que headerFields est [String: String] Dictionary et que le compilateur se plaint de passer [NSObject: AnyObject].