gpt4 book ai didi

android - 从 Android 应用程序进行身份验证时,Passport JS req.user 未定义

转载 作者:行者123 更新时间:2023-11-30 02:37:49 27 4
gpt4 key购买 nike

我正在 nodeJS 中开发一个 API,对于身份验证部分,我使用的是 PassportJS。我正在使用这个很好的教程:http://scotch.io/tutorials/javascript/easy-node-authentication-setup-and-local

在浏览器中,我可以获取用户,但是当我尝试使用 Android 应用程序时,req.user 未定义。

app.post('/login', passport.authenticate('local-login', {
successRedirect: '/loginSuccess',
failureRedirect: '/loginFailure',
failureFlash : true // allow flash messages
}));

app.get('/loginFailure', function(req, res, next) {
res.setHeader('Content-Type', 'application/json');
res.json({user: req.user, message: req.flash('loginMessage')[0]});
});

app.get('/loginSuccess', function(req, res, next) {
console.log(req.user);
res.setHeader('Content-Type', 'application/json');
res.json({user: req.user, message: "test"});
});

//

passport.use('local-login', new LocalStrategy({
usernameField : 'login',
passwordField : 'password',
passReqToCallback : true // allows us to pass in the req from our route (lets us check if a user is logged in or not)
},
function(req, login, password, done) {
// asynchronous
process.nextTick(function() {
User.findOne({$or:[{'local.email': login.toLowerCase()}, {'local.login': login}]}, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);

// if no user is found, return the message
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.'));

if (!user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));

// all is well, return user
else
return done(null, user);
});
});

}));

还有我的安卓代码:

public class LoginActivity extends Activity {

private Button loginButton = null;
private Button cancelButton = null;


private boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(AppInfo.getAppContext().CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}

private OnClickListener clickListenerLoginButton = new OnClickListener() {
@Override
public void onClick(View v) {
if (!isOnline()) {
Toast.makeText(LoginActivity.this, getResources().getString(R.string.ERROR_NO_NETWORK), Toast.LENGTH_LONG).show();
return ;
}
new LoginOperation().execute(getResources().getString(R.string.urlLogin));
}
};

private OnClickListener clickListenerCancelButton = new OnClickListener() {
@Override
public void onClick(View v) {
Intent result = new Intent();
setResult(RESULT_CANCELED, result);
finish();
}
};

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);

loginButton = (Button)findViewById(R.id.loginButton);
cancelButton = (Button)findViewById(R.id.cancelButton);

loginButton.setOnClickListener(clickListenerLoginButton);
cancelButton.setOnClickListener(clickListenerCancelButton);
}

private Object user;

private class LoginOperation extends AsyncTask<String, Void, Void> {

String Response = "";
String Error = null;
String data ="";
private ProgressDialog Dialog = new ProgressDialog(LoginActivity.this);
EditText login_emailEditText = (EditText) findViewById(R.id.login_emailEditText);
EditText passwordEditText = (EditText) findViewById(R.id.passwordEditText);

protected void onPreExecute() {

Dialog.setMessage("Please wait..");
Dialog.show();

try{
data += "&"+URLEncoder.encode("login", "UTF-8")+ "=" +URLEncoder.encode(login_emailEditText.getText().toString(), "UTF-8");
data += "&"+URLEncoder.encode("password", "UTF-8")+ "=" +URLEncoder.encode(passwordEditText.getText().toString(), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

}

@Override
protected Void doInBackground(String... urls) {
BufferedReader reader=null;
try
{
URL url = new URL(urls[0]);
// Send POST data request
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();

// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;

// Read Server Response
while((line = reader.readLine()) != null) {
sb.append(line + " ");
}

// Append Server Response To Content String
Response = sb.toString();
}
catch(Exception ex) {
Error = ex.getMessage();
}
finally {
try {
reader.close();
}
catch(Exception ex) {}
}
return null;
}

protected void onPostExecute(Void unused) {
Dialog.dismiss();

if (Error != null) {
Toast.makeText(LoginActivity.this, "ErrorAndroid: " + Error, Toast.LENGTH_LONG).show();
} else {
try {
JSONObject jsonObject = new JSONObject(Response);
Toast.makeText(LoginActivity.this, jsonObject.toString(), Toast.LENGTH_LONG).show();
user = jsonObject.get("user");
} catch (JSONException e) {
Toast.makeText(LoginActivity.this, "ErrorAndroidJSON: " + e.getMessage(), Toast.LENGTH_LONG).show();
}

}
}

}
}

然后尝试使用浏览器:用户 1/密码 1

http://exemple.com:4040/login

我使用的是 express4.0,但我也尝试过 express3.8。我完全迷路了,我完全不明白为什么它可以在浏览器上使用,但不能在应用程序上使用。

编辑:我认为问题出在我在 android 中调用 API 的方式,http header 请求应该与浏览器不同,所以它不能正常工作。

感谢您的帮助。

最佳答案

您的 expressjs 服务器正在返回 302 临时移动

    HTTP/1.1 302 Moved Temporarily
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
Location: /loginSuccess
Vary: Accept
Content-Type: text/html; charset=UTF-8
Content-Length: 82
Date: Wed, 08 Oct 2014 23:29:31 GMT
Connection: keep-alive

"Location" 设置为 /loginSuccess

Android URLConnection 默认情况下自动跟随重定向,并为您获取 /loginSuccess 返回的数据

问题是,您的 expressjs 服务器要求您发回它设置的 cookie;

所以解决办法是

  • 禁用自动重定向;在初始 url.openConnection()

    之后添加以下行
    ((HttpURLConnection)conn).setInstanceFollowRedirects(false);
  • 手动跟随 url 重定向,在 GET 请求中设置 cookie 值。在 wr.flush();

    之后添加以下代码 fragment
    String cookie = conn.getHeaderField("Set-Cookie");
    conn = new URL("http://example.com:4040/loginSuccess").openConnection();
    conn.setRequestProperty("Cookie", cookie);
    conn.connect();
  • 考虑将上面的硬编码 url 替换为 "baseUrl + conn.getHeaderField("Location")"

关于android - 从 Android 应用程序进行身份验证时,Passport JS req.user 未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26221101/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com