2016-07-29 74 views
2

In meinem AuthController.js ich überprüfen, ob Login sucessful ist und legen Sie einen Hash-Code in der Sitzung:Passport.js Sitzungen festgelegt sind nicht, wenn Anmeldung mit Android

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(); 

         } 
        }); 
       }) 

      }) 

Die Sessions gesetzt werden, wenn ich mit einem Browser anmelden - ich überprüfe sie mit ein anderen einfachen Controller:

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

als ich mit meiner Android-App (Volley Request) aller Arbeit anmelden, wie erwartet, aber als ich dann nach der erfolgreichen Anmeldung eine neue Anfrage an diesem ‚wer‘ Controller machen Das gesamte 'Pass' Attribut ist null.

Warum ist die Passsitzung nicht festgelegt, wenn ich mich mit der Android App anmelde?

Die Frage ist: Sind Volley Anforderungen anders als Browser Anfragen? Wenn der Server die Sitzung nicht für Volley-Anfragen speichern kann, wie weiß ich auf dem Server (bei der zweiten Anfrage), dass der Benutzer bereits angemeldet ist?

ich die req.headers Dump, ist dies, wie Chrome aussieht:

{ 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"' } 

Und das ist, wie Android Anfrage über Volley wie folgt aussieht:

{ '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' } 

Der Sitzungs Teil fehlt - mittlerweile Ich weiß, dass Sie das Session-Management selbst implementieren müssen. Gibt es ein einfaches Tutorial für mehrere HTTP-Anfragen über Volley mit Sitzungen?

Antwort

2

Ok 10 Tage später weiß ich, wie man das "repariert".

Wenn Sie eine Anfrage an Ihren Server stellen, erhalten Sie eine Menge Dinge zurück. Der Header ist das Wichtigste für uns. hier

mehr über HTTP-Header lesen: http://code.tutsplus.com/tutorials/http-headers-for-dummies--net-8039

HTTP-Anfragen sind staatenlos, das heißt, es nicht Informationen speichern und Staaten über den Client.

Volley behandelt keine Header. Was wir tun müssen, ist:

Wenn wir die erste Anfrage von unserer App machen, müssen wir die Antwort Header-Informationen speichern.

{"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>"} 

Die wichtige Information in der Kopfzeile ist der "set-cookie" -Teil. Wir müssen diese Informationen vom ersten Aufruf speichern und sie bei jeder nächsten Anforderung wiederverwenden, damit der Server weiß, wer wir sind.

Wie?

Ich habe diese benutzerdefinierte Anfrage von djodjo verwendet. Die wichtige Methode ist die parseNetworkResponse: https://stackoverflow.com/a/36435582/3037960

Und wir verwenden diese Klasse wie folgt aus:

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); 

Sie sehen dort die Zeile mit dem Session-Manager ... Sitzung.storeSailsSession (sailsSession); Dies ist eine benutzerdefinierte Klasse zum Speichern unseres Cookies in der gemeinsamen Einstellung, sodass wir diese Informationen in der App insgesamt abrufen können, wenn wir sie benötigen.

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); 
    } 

    } 

Sie sehen jetzt, wie Sie die Cookies aus der Kopfzeile erhalten, wie Sie sie für später speichern; und jetzt für die nex anfrage, wie man den header setzt?

Bevor Sie Ihre Anfrage senden (Sie müssen nicht die benutzerdefinierte MetaRequest von oben verwenden müssen) Sie Ihre Sitzung aus dem gemeinsamen Vorliebe bekommen müssen und es dann in den Hash-Karte mHeaders gesetzt:

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

und vergessen Sie nicht zurück, dass mHeaders auf Ihre Anfrage wie folgt aus:

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

normalerweise nur Sie neue WhatEverRequest verwenden (....); aber jetzt müssen Sie die befestigen {... return mHeaders;}

Ich hoffe, dass Sie es verstehen, sonst nur einen Kommentar, ich es erklären werde. Für mich hat es funktioniert, also bin ich mir sicher, dass es auch für dich funktioniert. Für das nächste Mal empfehle ich Ihnen zu verwenden https://jwt.io

+0

Ich wieder, 1,5 Monate später: Verwenden Sie RETROFIT! Retrofit ist wie 1000 Mal einfacher und besser - ich wünschte, ich wüsste es https://futurestud.io/tutorials/retrofit-add-custom-request-header – Suisse