使用Androidlogin时,Passport.js会话未设置

在我的AuthController.js中,我检查login是否成功,并在会话中设置一个哈希码:

req.logIn(user, function (err) { if (err) res.send(err); var redirectTo = req.session.redirectTo ? req.session.redirectTo : '/user/show/'+user.id; delete req.session.redirectTo; bcrypt.genSalt(10, function (err, salt) { bcrypt.hash(user.email, salt, function (err, hash) { if (err) { console.log(err); } else { req.session.passport.user_type = user.type; req.session.passport.user_avatar = user.avatar; req.session.passport.email = user.email; req.session.passport.token = hash; // here session is set! also when login with Android console.log("User passport Sessions: ",req.session.passport) res.json(user); res.end(); } }); }) }) 

当我用浏览器login时会话被设置 – 我用另一个简单的控制器检查他们:

 'who': function (req, res) { res.json(req.session); }, 

当我用我的Android应用程序(Volley请求)login时,一切都按预期工作,但是当我成功login后向这个“who”控制器发出一个新请求时,整个“passport”属性为空。

为什么在loginAndroid App时护照会话没有设置?

问题是:排除的请求是否与浏览器请求不同? 当服务器不能保存会话的抽象请求,我怎么在服务器知道(第二个请求),用户已经login?

我转储req.headers,这是Chrome的样子:

 { host: 'localhost:1337', connection: 'keep-alive', 'cache-control': 'max-age=0', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36', accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'accept-encoding': 'gzip, deflate, sdch', 'accept-language': 'de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4', cookie: '__utma=111872281.1508283337.1455636609.1455636609.1455636609.1; __utmz=111872281.1455636609.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _ga=GA1.1.1508283337.1455636609; sails.sid=s%3AHNW3D3ktwA79IFHH4gX9Ko6o73MZOjRK.I7sTYkCKSkkwset6OC2ap58fcROPtV6PqUnkaInGW44', 'if-none-match': 'W/"1f3e-WoreHgYUy3uvXGNH++ttsQ"' } 

这就是Android对于Volley的要求:

 { 'user-agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0; Android SDK built for x86 Build/MASTER)', host: '10.0.2.2:1337', connection: 'Keep-Alive', 'accept-encoding': 'gzip' } { 'if-none-match': 'W/"1f3e-WoreHgYUy3uvXGNH++ttsQ"', 'user-agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0; Android SDK built for x86 Build/MASTER)', host: '10.0.2.2:1337', connection: 'Keep-Alive', 'accept-encoding': 'gzip' } 

会议部分丢失 – 同时我知道你必须自己实施会话pipe理。 是否有一个简单的教程通过会议与排气多个HTTP请求?

好的10天后,我知道如何“修复”这一点。

当你向你的服务器发出请求时,你会得到一堆东西。 标题对我们来说很重要。

阅读更多关于HTTP头文件: http : //code.tutsplus.com/tutorials/http-headers-for-dummies–net-8039

HTTP请求是无状态的,也就是说,它不保存有关客户端的信息和状态。

排雷不处理标题。 我们要做的是:

当我们从我们的应用程序发出第一个请求时,我们必须保存响应头信息。

 {"Access-Control-Allow-Credentials":"","Access-Control-Allow-Headers":"","Access-Control-Allow-Methods":"","Access-Control-Allow-Origin":"","Access-Control-Expose-Headers":"","Connection":"keep-alive","Content-Length":"235","Content-Type":"application\/json; charset=utf-8","Date":"Tue, 09 Aug 2016 22:39:40 GMT","ETag":"W\/\"eb-bxZXjFIir0ihzYNPgoUbTg\"","set-cookie":"sails.sid=s%3AsjQL1FsAJY5VWGHdgChpa0hgZPs06AH9z.H1RLNh%2FMqLjxdGtKtnWFv8cFO8WjeAUhPFQp2Yl73Lo; Path=\/; HttpOnly","Vary":"X-HTTP-Method-Override","X-Android-Received-Millis":"1470713694296","X-Android-Response-Source":"NETWORK 200","X-Android-Selected-Protocol":"http\/1.1","X-Android-Sent-Millis":"1470713694119","X-Powered-By":"Sails <sailsjs.org>"} 

标题中的重要信息是“set-cookie”部分。 我们必须从第一次调用中保存这些信息,并在接下来的每个请求中重复使用它,以便服务器知道我们是谁。

怎么样?

我从djodjo使用了这个自定义请求。 重要的方法是parseNetworkResponse : https : //stackoverflow.com/a/36435582/3037960

我们使用这样的类:

 mHeaders = new HashMap<String, String>(); session = new SessionManager(myView.getContext()); registerRequest = new MetaRequest(1, MY_ENDPOINT, obj, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { JSONObject headers = new JSONObject(); try { headers.put("headers", response.get("headers")); // get the "set-cookie" value String sailsSession = String.valueOf(headers.getJSONObject("headers").get("set-cookie")); Log.d("Response Headers", sailsSession); // Session Manager session.storeSailsSession(sailsSession); String cookie = session.getSailsSession(); if( cookie != null) { //just to test if the cookie is now saved? Log.d("Cookies", cookie); } } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d("ERROR", String.valueOf(error)); // TODO Auto-generated method stub } }){ public Map<String, String> getHeaders() { return mHeaders; } }; RequestQueue queue = Volley.newRequestQueue(getActivity()); queue.add(registerRequest); 

你看到那里的会话pipe理器… session.storeSailsS​​ession(sailsS​​ession); 这是一个自定义类,用于将Cookie保存在共享首选项中,以便我们可以在需要时在应用程序中整体获取这些信息。

 public class SessionManager { // Shared Preferences SharedPreferences pref; // Editor for Shared preferences Editor editor; // Context Context _context; // User hash/cookie public static final String KEY_SESSION = "session"; // Constructor public SessionManager(Context context){ this._context = context; pref = _context.getSharedPreferences(PREF_NAME, 0); editor = pref.edit(); } public void storeSailsSession(String session){ editor.putString(KEY_SESSION,session); editor.commit(); } public String getSailsSession(){ return pref.getString(KEY_SESSION,null); } } 

你现在看到如何从标题中获取cookie,以后如何存储它们; 现在为nex请求如何设置标题?

在发送请求之前(您不必使用上面的自定义MetaRequest),必须从共享首选项中获取会话,然后将其设置在哈希映射mHeaders中:

 String sailsCookie = session.getSailsSession(); mHeaders.put("cookie", sailsCookie.toString()); 

并且不要忘记把这个mHeaders返回给你的请求,像这样:

 JsonArrayRequest arrayreq = new JsonArrayRequest(JsonURL,Listener,ErrorListener){ public Map<String, String> getHeaders() { return mHeaders; } } 

通常你只使用新的WhatEverRequest(….); 但现在你必须附加{…返回mHeaders;}

我希望你能理解,否则只是发表评论,我会解释一下。 对我来说,它的工作,所以我相信它也会为你工作。 下次我推荐你使用https://jwt.io