Android OAuth认证

来源:互联网 发布:微信钱包表结构 mysql 编辑:程序博客网 时间:2024/04/19 04:01
还是拿人人的OAuth认证举例吧。其实这个认证就是原则上实现了程序开发人员和用户的用户名密码的分离,使密码不会被第三方获取。
   只有被认证后,才能有权限调用人人网的接口方法。首先要去人人的开放平台去注册,各种信息都填好后,会给你一个API key和一个Secret key.
  首先,浏览器跳转到人人指定的授权服务页面,"https://graph.renren.com/oauth/authorize?client_id=XXX&response_type=code&redirect_uri=http://graph.renren.com/oauth/login_success.html";client_id就是你申请的API Key.。redirect_uri就是页面的跳转,这里使用人人给的默认页面

webview=(WebView)findViewById(R.id.webview);
        webview.getSettings().setJavaScriptEnabled(true);//不设置这个按钮不管用
        webview.getSettings().setBuiltInZoomControls(true);
        webview.setWebViewClient(new WebViewClient(){
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                        // TODO Auto-generated method stub
                        view.loadUrl(url);
                        return true;
                }//如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。给WebView添加一个事件监听对象(WebViewClient)并重写其中的一些方法:
shouldOverrideUrlLoading:对网页中超链接按钮的响应。当按下某个连接时WebViewClient会调用这个方法,并传递参数

                @Override
                public void onReceivedSslError(WebView view,
                                SslErrorHandler handler, SslError error) {
                        // TODO Auto-generated method stub
                        handler.proceed();
                }
                @Override
                public void onPageFinished(WebView view, String url) {
//当网页结束时回调该方法,这时服务器会向url尾部追加参数code,这个就是Authorization Code
                        // TODO Auto-generated method stub
                        url1=webview.getUrl();
                        if(url1!=null){//以下方法就是从url里截取code
                                String tString;
                                if (url1.contains("code="))
                                        {
                                                tString = url1.substring(url1.indexOf("code=") + 5, url1.length());
                                                MyApplication.getInstance().code=tString;
                                                if(MyApplication.getInstance().code!="")
                                                {
                             Intent intent=new Intent(AuthorizationActivity.this,WaitActivity.class);
                             startActivity(intent);
                                                }
                                        }
                        }
                        super.onPageFinished(view, url);
                }
        });
         String url="https://graph.renren.com/oauth/authorize?client_id=0049faf6b6d045c1ssdd333a0f38e3c&response_type=code&redirect_uri=http://graph.renren.com/oauth/login_success.html";
        webview.loadUrl(url);

第二步就是获取Authorization Code了。
   需要发送请求(我用的POST)到“https://graph.renren.com/oauth/token”,并传递以下参数:
grant_type:固定值“authorization_code”。
code:上一步你获得的Authorization Code;
client_id:应用的API Key;
client_secret:应用的Secret Key;
redirect_uri:必须与获取Authorization Code时传递的“redirect_uri”保持一致。
发送完请求,服务器会返回给你一个JSON文件。自己解析,就会获得access_token,expires_in,refresh_token三个字符串,建议保存在SQLite或SharedPreference里,可以多次使用,貌似是两个月。
核心代码
        url=new URL("https://graph.renren.com/oauth/token?");
                                        mHttpURLConnection=(HttpURLConnection) url.openConnection();
                                        mHttpURLConnection.setDoInput(true);//设置Input有效
                                        mHttpURLConnection.setDoOutput(true);
                                        String grant_type=     "grant_type=authorization_code";
                                        String code=           "&code="+MyApplication.getInstance().code;
                                        String client_id=      "&client_id=0049faf6b6d0s45c18dbed333a0f38e3c";
                                        String client_secret=  "&client_secret=d691227sfd46d474bab756de9815c677c";
                                        String redirect_uri=   "&redirect_uri=http://graph.renren.com/oauth/login_success.html";
                                        out=mHttpURLConnection.getOutputStream();
                                        out.write((grant_type+code+client_id+client_secret+redirect_uri).getBytes());
                                        out.flush();
                                    in=mHttpURLConnection.getInputStream();
                                    JsonParse parse=new JsonParse();
                                    Map<String,String> map=parse.TokenparseJson(in);//自己写的JSON文件解析的方法,我源代码里有
                                    MyApplication.getInstance().tokenMap=map;
                                    SharedPreferences preferences=getSharedPreferences("oauth", MODE_WORLD_WRITEABLE);//三个参数可复用,所以保存起来
                                    SharedPreferences.Editor editor=preferences.edit();
                                    editor.putString("access_token", map.get("access_token"));
                                    editor.putString("expires_in", map.get("expires_in"));
                                    editor.putString("refresh_token", map.get("refresh_token"));
                                    editor.commit();


  接下来就是要得到Session Key,其实这步可以省略,貌似以前只有获得了Session Key才能调用接口的方法,但是现在直接用access_token就可以了,不过还是讲讲怎么获取吧。
    POST请求到https://graph.renren.com/renren_api/session_key,写入参数oauth_token=your access_token
    核心代码:
        url = new URL("https://graph.renren.com/renren_api/session_key");
                        HttpURLConnection mHttpURLConnection=(HttpURLConnection)url.openConnection();
                        mHttpURLConnection.setDoInput(true);
                        mHttpURLConnection.setDoOutput(true);
                        String pramar="oauth_token="+MyApplication.getInstance().tokenMap.get("access_token");
                        OutputStream out=mHttpURLConnection.getOutputStream();
                        out.write(pramar.getBytes());
                        out.flush();
                        InputStream in=mHttpURLConnection.getInputStream();
                        byte[] byt=new byte[1024];//不知道为什么,使用BuffedReader循环读取总是有问题,曲线救国了
                        int a=in.read(byt);//调试的时候可以看看那个JSON是什么样子的,在自己写个解析方法
                        String tempString=new String(byt, 0, a, "UTF-8");
                        String jsonString="["+tempString+"]";
                        JSONArray jsonArray=new JSONArray(jsonString);
                        JSONObject object=jsonArray.getJSONObject(0);
                        JSONObject renren_token=object.getJSONObject("renren_token");
                        session_key=renren_token.getString("session_key");
                        MyApplication.getInstance().session_key=session_key;


该获得的都得到了,该调用API了,但是在这之前还有一项最重要的工作-——签名,据人人网称,这是为了防止你的Sercret key被盗用。以users.getLoggedInUser这个API为例

String v1="1.0";
        String api_key1="0049faf6b6d045c18dbqed333a0f38e3c";
        String format1="JSON";//要把人人网每个API规定的必须参数按照字典升序排列,之后追加Sercret Key在末尾,经过MD5算法,得到的字符串就是你的签名了
        String session_key1=MyApplication.getInstance().session_key;
        public String getLoggedInUser(){
                GetSignatureM mGetSignatureM=new GetSignatureM();
                List<String> paramList=new ArrayList<String>();
                paramList.add("v="+v1);
                paramList.add("api_key="+api_key1);
                paramList.add("format="+format1);
                paramList.add("session_key="+session_key1);
                paramList.add("method=users.getLoggedInUser");
                String sig1=mGetSignatureM.getSignature(paramList, "d691227fds46d474bab756de9815c677c");
                try {
                        String method=URLEncoder.encode("users.getLoggedInUser","UTF-8");
                        String session_key=URLEncoder.encode(session_key1,"UTF-8");
                        String api_key=URLEncoder.encode(api_key1,"UTF-8");
                        String format=URLEncoder.encode(format1,"UTF-8");
                        String v=URLEncoder.encode(v1,"UTF-8");
                        String sig=URLEncoder.encode(sig1,"UTF-8");
                        HttpPost mHttpPost=new HttpPost();
                        String url="http://api.renren.com/restserver.do";
                        String parmar="method="+method+"&session_key="+session_key+"&api_key="+api_key+"&format="+format+"&v="+v+"&sig="+sig;
                        InputStream in=mHttpPost.doPost(url, parmar);
                        byte[] b=new byte[1024];
                        int a=in.read(b);
                        String line="["+new String(b, 0, a,"UTF-8")+"]";
                        return line;

MD5算法

Collections.sort(paramList);
                 StringBuffer buffer = new StringBuffer();
                 for (String param : paramList) {
                     buffer.append(param);  //将参数键值对,以字典序升序排列后,拼接在一起
                 }
                 buffer.append(secret);  //符串末尾追加上应用的Secret Key
                 try {            //下面是将拼好的字符串转成MD5值,然后返回
                    java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
                    StringBuffer result = new StringBuffer();
                    try {
                        for (byte b : md.digest(buffer.toString().getBytes("UTF-8"))) {
                            result.append(Integer.toHexString((b & 0xf0) >>> 4));
                            result.append(Integer.toHexString(b & 0x0f));
                        }
                    } catch (UnsupportedEncodingException e) {
                        for (byte b : md.digest(buffer.toString().getBytes())) {
                            result.append(Integer.toHexString((b & 0xf0) >>> 4));
                            result.append(Integer.toHexString(b & 0x0f));
                        }
                    }
                    return result.toString();

这样就能调用API了

原创粉丝点击