博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OAuth认证(完整版)
阅读量:6171 次
发布时间:2019-06-21

本文共 9623 字,大约阅读时间需要 32 分钟。

拿人人的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)到“”,并传递以下参数:
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
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请求到,写入参数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
paramList=new ArrayList
(); 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了

 

转自

转载于:https://www.cnblogs.com/neilyo/archive/2011/11/15/2249243.html

你可能感兴趣的文章
Scala并发编程【消息机制】
查看>>
win10下安装Oracle 11g 32位客户端遇到INS-13001环境不满足最低要求
查看>>
AngularJS-01.AngularJS,Module,Controller,scope
查看>>
【MySQL 安装过程1】顺利安装MySQL完整过程
查看>>
Inno Setup入门(二十)——Inno Setup类参考(6)
查看>>
图片自适应
查看>>
amd cmd
查看>>
Linux下的uml画图工具
查看>>
xml返回数组数据
查看>>
约瑟夫问题总结
查看>>
spring mybatis 批量插入返回主键
查看>>
指针函数小用
查看>>
开源力量公开课第二十三期-从SVN到Git,次时代代码管理
查看>>
输入挂
查看>>
升级迁移前,存储过程统计各个用户下表的数据量,和迁移后的比对
查看>>
sql注入分类
查看>>
初识CSS选择器版本4
查看>>
[Hadoop in China 2011] 朱会灿:探析腾讯Typhoon云计算平台
查看>>
JavaScript之数组学习
查看>>
PHP 设置响应头来解决跨域问题
查看>>