今天再講一下android如何通過Cooki訪問需要身分識別驗證的web API。
web API項目中加入如下用於驗證身份的Controler:
public class LogonController : ApiController { public bool Post([FromBody]User model) { using (var db = new HereDbContext()) { var query = db.AllUsers.Where((p) => p.Name == model.Name && p.Password == model.Password); if (query.Count() > 0) {
// 將用戶端驗證儲存到Cooki中 FormsAuthentication.SetAuthCookie(model.Name, false); return true; } } return false; } }
web API中存在另一個需要身分識別驗證才能使用的API Controler,如下:
[Authorize] public class UsersController : ApiController { public IEnumerable<User> GetAllUsers() { Log.I("GetAllUsers() is called."); using (var db = new HereDbContext()) { return db.AllUsers.ToList(); } } public User GetUserById(int id) { using (var db = new HereDbContext()) { var user = db.AllUsers.FirstOrDefault((p) => p.Id == id); if (user == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } return user; } } public User GetUsersByUid(string uid) { using (var db = new HereDbContext()) { foreach (var user in db.AllUsers) { if (user.UID == uid) { return user; } } } throw new HttpResponseException(HttpStatusCode.NotFound); } public HttpResponseMessage AddUser([FromBody]User user) { if (user == null) { return Request.CreateResponse<string>(HttpStatusCode.Forbidden, "user is null!"); } using (var db = new HereDbContext()) { if (db.AllUsers.Where((p) => string.Equals(p.Name, user.Name)).Count() > 0) { return Request.CreateResponse<string>(HttpStatusCode.Conflict, user.Name + " already existed!"); } db.AllUsers.Add(user); db.SaveChanges(); return Request.CreateResponse<string>(HttpStatusCode.Accepted, user.UID); } } }
如果我們想通過android用戶端訪問這個需要身分識別驗證web API。我們可以通過如下方式書寫用戶端:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.List;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.CookieStore;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.client.methods.HttpUriRequest;import org.apache.http.impl.client.AbstractHttpClient;import org.apache.http.impl.client.DefaultHttpClient;import android.util.Log;public abstract class HttpHelper { private final static String TAG = "HttpHelper"; private final static String API_URL = "http://your.url/api/"; private static CookieStore sCookieStore; public static String invokePost(String action, List<NameValuePair> params) { try { String url = API_URL + action + "/"; Log.d(TAG, "url is" + url); HttpPost httpPost = new HttpPost(url); if (params != null && params.size() > 0) { HttpEntity entity = new UrlEncodedFormEntity(params, "UTF-8"); httpPost.setEntity(entity); } return invoke(httpPost); } catch (Exception e) { Log.e(TAG, e.toString()); } return null; } public static String invokePost(String action) { return invokePost(action, null); } public static String invokeGet(String action, List<NameValuePair> params) { try { StringBuilder sb = new StringBuilder(API_URL); sb.append(action); if (params != null) { for (NameValuePair param : params) { sb.append("?"); sb.append(param.getName()); sb.append("="); sb.append(param.getValue()); } } Log.d(TAG, "url is" + sb.toString()); HttpGet httpGet = new HttpGet(sb.toString()); return invoke(httpGet); } catch (Exception e) { Log.e(TAG, e.toString()); } return null; } public static String invokeGet(String action) { return invokeGet(action, null); } private static String invoke(HttpUriRequest request) throws ClientProtocolException, IOException { String result = null; DefaultHttpClient httpClient = new DefaultHttpClient(); // restore cookie if (sCookieStore != null) { httpClient.setCookieStore(sCookieStore); } HttpResponse response = httpClient.execute(request); StringBuilder builder = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader( response.getEntity().getContent())); for (String s = reader.readLine(); s != null; s = reader.readLine()) { builder.append(s); } result = builder.toString(); Log.d(TAG, "result is ( " + result + " )"); // store cookie sCookieStore = ((AbstractHttpClient) httpClient).getCookieStore(); return result; }}
需要注意的是,調試過程中,需要先將web API宿主到IIS,並且IIS需要將form身分識別驗證開啟。