Android JWT Example
這個例子主要要透過Restful Api 在後台登入後,取得token.經由驗證後將資料POST 至後台
POST 至後台的結果
首先在POSTMAN 中先驗證一下API,這是未經驗證的Token,無法post 文章
接下來要在Android 中執行
我們將SharePreference 的讀取程式設定在Application
在mainfest 中 application 要加上
<application
android:name=".MainApp"
....
/>
在主頁面的Layout 設定為
在MainActivity中的OnCreate中先檢查,是否有取得之前存在sharepreference 的資料
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ed_user = findViewById(R.id.user);
ed_pwd = findViewById(R.id.pwd);
app = (MainApp) getApplication();
if (!app.getUserName().equals("")) {
ed_user.setText(app.getUserName());
}
if (!app.getPwdName().equals("")) {
ed_pwd.setText(app.getPwdName());
}
}
主要的精髓在利用setRequestProperty 設定header 的訊息,再將須上傳的資料以json 包覆,以output 串流將資料送到後台.
如果正確取回資料時,conn.getResponseCode 會傳回200,這時再接InputStream 將token 取回來.透過gson 解析後,可以取得"access"
最後在透過MainApp 中的SetToken 方法,將Token 存回SharePreference
private void doAuthentication() {
new Thread(new Runnable() {
@Override
public void run() {
try{
URL url = new URL(app.getTokenURL());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(3000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");//設定訊息的型別
conn.setRequestProperty("Accept-Charset", "UTF-8");
JSONObject json = new JSONObject();//建立json物件
json.put("username", usr);
json.put("password",pwd);
conn.connect();
Log.v("Jacky","json:"+json.toString());
OutputStream out = conn.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
out.write(json.toString().getBytes());//把json字串寫入緩衝區中
out.flush();//重新整理緩衝區,把資料傳送出去,這步很重要
out.close();
bw.close();//使用完關閉
int responseCode = conn.getResponseCode();
Log.v("Jacky","responseCode:"+responseCode);
InputStream in = conn.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
BufferedReader br = new BufferedReader(reader);
String line = br.readLine();
Gson gson = new Gson();
Token token = gson.fromJson(line, new TypeToken<Token>(){}.getType());
app.setToken(token.getAccess());
}catch (Exception e){
for (StackTraceElement se: e.getStackTrace())
Log.v("Jacky",se.toString());
Log.v("Jacky",e.toString());
}
}
}).start();
最後透過Intent 將資料送到ReadingActivity
在ReadingActivity 的Layout 配置,三個EditText,一個Button
在ReadingActivity 的OnCreate 事件中利用JWT 類別來解析token,取得jwt.getClaim(“user_id”) 並轉成字串
token = app.getToken();
JWT jwt = new JWT(token);
Map<String, Claim> allClaims = jwt.getClaims();
id = jwt.getClaim("user_id").asString();
Log.v("Jacky", id);
使用JWT 需先於gradle 中載入
implementation 'com.auth0.android:jwtdecode:2.0.0'
在button 中為了將資料Post 到後台需要以執行緒來處理
在Api 中需要將token 的資訊傳到後台,以setRequestProperty 來處理
conn.setRequestProperty("Authorization","Bearer " + token);public void doPost(View view) {
title = ed_title.getText().toString();
category = ed_category.getText().toString();
content = ed_content.getText().toString();
new Thread(
new Runnable() {
@Override
public void run() {
try {
URL url = new URL(app.getUrl());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(3000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");//設定訊息的型別
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setRequestProperty("Authorization","Bearer " + token);
JSONObject json = new JSONObject();//建立json物件
json.put("title", title);//使用URLEncoder.encode對特殊和不可見字元進行編碼
json.put("category",category);
json.put("content",content);
json.put("user", id);
conn.connect();
OutputStream out = conn.getOutputStream();//輸出流,用來發送請求,http請求實際上直到這個函式裡面才正式傳送出去
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));//建立字元流物件並用高效緩衝流包裝它,便獲得最高的效率,傳送的是字串推薦用字元流,其它資料就用位元組流
out.write(json.toString().getBytes());//把json字串寫入緩衝區中
out.flush();//重新整理緩衝區,把資料傳送出去,這步很重要
out.close();
bw.close();//使用完關閉
int responseCode = conn.getResponseCode();
Log.v("Jacky","responseCode:"+responseCode);
if (responseCode >= 400 ) {
InputStream in = conn.getErrorStream();
InputStreamReader reader = new InputStreamReader(in);
BufferedReader br = new BufferedReader(reader);
Log.v("Jacky",""+br.readLine());
}else{
InputStream in = conn.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
BufferedReader br = new BufferedReader(reader);
Log.v("Jacky",""+br.readLine());
}
}catch (Exception e){
for (StackTraceElement st :e.getStackTrace())
Log.v("Jacky",""+st.toString());
}
}
}
).start();
}
完整的程式請參考