今天再讲一下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身份验证打开。