[英]LaravelPhp Sanctum Login Authentication Android Java
I have a fully working SPA website built with LaravelPhp 8 Sanctum authentication and Vuejs.我有一个使用 LaravelPhp 8 Sanctum 身份验证和 Vuejs 构建的完全可用的 SPA 网站。 Now I'm building an Android app that uses the same APIs.
现在我正在构建一个使用相同 API 的 Android 应用程序。 Connecting to APIs that don't require authentication works perfectly but protected APIs don't.
连接到不需要身份验证的 API 可以完美运行,但受保护的 API 则不然。 I send POST to login and it works but after that no other protected API work.
我发送 POST 来登录,它可以工作,但之后没有其他受保护的 API 工作。 It returns error 401 (x-android-response-source: NETWORK 401) Do I use a session cookie and then how do I set a session cookie?
它返回错误 401 (x-android-response-source: NETWORK 401) 我是否使用会话 cookie,然后如何设置会话 cookie? Thank you.
谢谢你。
this is how SPA works:这就是 SPA 的工作原理:
Here is config/auth.php (on API it says token but I never used tokens in my SPA)这是 config/auth.php (在 API 上它说令牌,但我从未在我的 SPA 中使用过令牌)
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
routes/api.php路线/api.php
Route::post('login', ['as' => 'login', 'uses' => 'App\Http\Controllers\LoginController@login']);
Route::middleware(['auth:sanctum'])->group(function () {
Route::get('customer', 'App\Http\Controllers\CustomerController@show');
}
.env: .env:
SANCTUM_STATEFUL_DOMAINS=mywebsite.si
SESSION_DOMAIN=.mywebsite.si
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
(Android) Http.java (Android) Http.java
public class Http {
Context context;
private String url, method = "GET", data = null, response = null;
private Integer statusCode = 0;
private LocalStorage localStorage;
public Http(Context context, String url) {
this.context = context;
this.url = url;
localStorage = new LocalStorage(context);
}
public void setMethod(String method) {
this.method = method.toUpperCase();
}
public void setData(String data) {
this.data = data;
}
public String getResponse() {
return response;
}
public Integer getStatusCode() {
return statusCode;
}
public void send() {
try {
URL sUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) sUrl.openConnection();
connection.setRequestMethod(method);
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("X-Requested-With", "XMLHttpRequest");
connection.setRequestProperty("Cookie", "Access-Control-Allow-Credentials=true; Access-Control-Allow-Origin=https://mywebsite.si;");
if (!method.equals("GET")) {
connection.setDoOutput(true);
}
if (data != null) {
OutputStream os = connection.getOutputStream();
os.write(data.getBytes());
os.flush();
os.close();
}
statusCode = connection.getResponseCode();
InputStreamReader isr;
if (statusCode >= 200 && statusCode <= 299) {
// if success response
isr = new InputStreamReader(connection.getInputStream());
} else {
// if error response
isr = new InputStreamReader(connection.getErrorStream());
}
BufferedReader br = new BufferedReader(isr);
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
response = sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
}
}
LoginActivity:登录活动:
String data = params.toString();
String url = getString(R.string.api_server) + "/login";
new Thread(new Runnable() {
@Override
public void run() {
Http http = new Http(LoginActivity.this, url);
http.setMethod("post");
http.setData(data);
http.send();
runOnUiThread(new Runnable() {
@Override
public void run() {
Integer code = http.getStatusCode();
if (code == 200) {
try {
JSONObject response = new JSONObject(http.getResponse());
} catch (JSONException e) {
e.printStackTrace();
}
} else if (code == 422) {
try {
JSONObject response = new JSONObject(http.getResponse());
String msg = response.getString("message");
alertFail(msg);
} catch (JSONException e) {
e.printStackTrace();
}
} else if (code == 401) {
try {
JSONObject response = new JSONObject(http.getResponse());
String msg = response.getString("message");
alertFail(msg);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(LoginActivity.this, "Error " + code, Toast.LENGTH_SHORT).show();
}
}
});
}
}).start();
UserActivity:用户活动:
String url = getString(R.string.api_server) + "/customer";
new Thread(new Runnable() {
@Override
public void run() {
Http http = new Http(UserActivity.this, url);
http.send();
runOnUiThread(new Runnable() {
@Override
public void run() {
Integer code = http.getStatusCode();
if (code == 200) {
try {
JSONObject response = new JSONObject(http.getResponse());
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(UserActivity.this, "Error " + code, Toast.LENGTH_SHORT).show();
}
}
});
}
}).start();
}
Response from login:来自登录的响应:
cache-control: no-cache, private
connection: Keep-Alive
content-type: application/json
date: Tue, 24 May 2022 10:19:21 GMT
keep-alive: timeout=5, max=100
transfer-encoding: chunked
vary: Origin
x-android-received-millis: 1653387298665
x-android-response-source: NETWORK 200
x-android-selected-protocol: http/1.1
x-android-sent-millis: 1653387298552
x-ratelimit-limit: 20
x-ratelimit-remaining: 18
You have to set header for auth:sanctum protected apis您必须为 auth:sanctum protected apis 设置标头
Authorization: Bearer <token-here>
if you're using sanctum in proper way you can generate token against auth models and use those to fetch Authorization: Bearer <token-here>
如果您以正确的方式使用 sanctum,您可以针对身份验证模型生成令牌并使用它们来获取
Have a look into this article https://www.twilio.com/blog/build-restful-api-php-laravel-sanctum看看这篇文章https://www.twilio.com/blog/build-restful-api-php-laravel-sanctum
Sanctum automatically checks the header and authenticate the user based on the token Sanctum 自动检查标头并根据令牌对用户进行身份验证
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.