asp.net实现OAuth认证服务端接口

网络海人民广播电视台湾大学有关OAuth的稿子,不过满含sina本人都都未有详细的的介绍,包蕴表明进度和认证后数据的积存,所以参照他事他说加以考察了Facebook的表达过程写下有些详细的讲解代码。

当今的网络是开放的互连网,你要想融入那些绽放的条件,当然自个儿也要开放一点。假如你希望外人能够很方便的应用你的网址上的客商及数码,当然要提
供相比较开放一点的接口。若是能够落到实处标准的OAuth认证接口,第三方客商在支付的时候就能轻松超级多,因为她们很也许在开荒博客园程序的时候已经做过相通的
事写过无数那样的代码了。

在大家带头前,大家先创设一张数据库来保存客商音讯,下边是叁个主干的 Mysql
的例证:

不过C#达成OAuth认证还真是挺烦的,紧即使,类库有一点点个,但是,都找不到文书档案。适用于顾客端实现的文书档案倒是有相当多,适用于劳动器端的的确未有。连类库的合俄文档都找不到,唯有源码里仅存的生龙活虎份简易Test能够作为参照他事他说加以侦查。费了全力以赴终于算是达成了多少个差相当少一模二样的OAuth认证接口,
记录一下。

CREATE TABLE `oauth_users` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `oauth_provider` VARCHAR(10),
  `oauth_uid` text,
  `oauth_token` text,
  `oauth_secret` text,
  `username` text,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

因而查找,比较,读能源,读源码,再比较,最终选项了oauth-dot-net这一个类库。尽管它已经一年多没更新了,曾经承诺的2.0接口也一向不动静,可是,它的Server端完结算是最轻易理解和操作的了。

注意 oauth_token 和 oauth_secret 那三个字段。sina的 OAuth 认证供给token 和 token_secret
四个参数来形成认证,所以大家须求预先流出八个字段来记录她们。

下载源码也好,Release版本也好,把一群dll引进到协调的等级次序中。关于那个类其余类别,直接用VS新建网址就能够,没有必要web
application,也没有须要web
service,也不供给WCF。可是呢,使用进度中您必要新建多少个类,而且这么些类必要在web.config中钦定,所以它供给总体的命名空间,简单起见,新建八个类库,把装有的类定义和通用的法子放到那中间,当然,因为我们的花色原来就有叁个用来定义类变量和国有措施的dll,就直接放一块了。

然后大家必要各种完成以下工作:

然后您供给贯彻多少个东西:ConsumerStore,CallbackStore,TokenGenerator,TokenStore,它们分
别落成自个儿的名字前面加上I的不行接口。具体如何落到实处以致各样函数的职能,能够参见源码中提供的InMemoryXXX的兑现情势。具体来讲,consumer是贰个个应用,可能第三方的交接网址,各种应用有个唯意气风发的appkey和appsecret,跟和讯的使用相通,你须要在这里刻实现依照appkey查找该consumer的成效,每一回诉求发起,都急需调用。因为创制应用日常的话有温馨的流水生产线,所以在此个store能够不用管它。
callback是调用者的回到UTucsonL,在提请request_token的时候会传送过来,要求保留下来到客户亲自授权完结今后再读出来进行跳转。
TokenGenerator唯有多个函数,用来生成新的request_澳门新葡萄京官网注册,token和access_token,怎样变化它当中的key和
secret,随意你自个儿,只要永恒不另行就能够了,嫌麻烦就径直用GUID。TokenStore是用来询问token的,举例依照tokenkey查
找request_token或者access_token,你能够用自个儿的数据库来兑现,字段也就那二个,也是然后种种央浼都要读取的。然则它自身的达成接口里面忽视了很入眼的少数,正是没有把access_token跟客商Id绑定起来,那一个确定要协调完成的,不然程序传叁个access_token
过来,你找不到是哪位合法顾客。

向 SinaAPI发起认证申请 注册/只怕登入,若是客商已经有帐号的景况下
将有关数据保存在 Session 中

贯彻了那多少个类以往,在源码里面找到OAuth.Net.Examples.EchoServiceProvider那么些示例项目,把它的
web.config里面包车型大巴oauth.net.serviceprovider和oauth.net.components两段配置音讯拷到自身的
web.config里面来,然后更正oauth.net.components那生龙活虎段中间对应的八个温馨曾经达成的类,指向自身的类库的职责。

依据 OAuth
的表达流程从调换多个网站开始。顾客被重定向到该网站必要验证,认证通过后,会重定向到大家的应用服务器,并会将五个申明后的参数通过
U奇骏L 情势传回。

然后添加二个global.asax,对于网址项目,那几个文件是一直不codefile文件的,可以直接在asax上面写代码,把示例项目中的那叁个Init方法复制过来。当时,功底工作就完成了。

建立index.php

接下来必要达成八个进度,申请request_token(这一步未有分界面,对方间接用代码读你的UEscortL获取那几个音讯),顾客跳到authorize
的页面,输入顾客名和密码,验证并授权给该顾客端,验证达成后归来客户内定的callbackurl,客商再拿该再次回到链接中的参数申请
access_token(这一步也还未分界面,通进度序间变成),保存下你回到的token和secret就足以用在其余具备的读取数据的乞请上了。

getRequestToken();
// Requesting authentication tokens, the parameter is the URL we will be redirected to
$aurl = $sinaOAuth->getAuthorizeURL( $keys['oauth_token'] ,false , 'http://t.yourtion.com/sina/callback.php');
// 保存到 session 中
$_SESSION['keys'] = $keys;
?>
Use Oauth to login

身体力行中朝气蓬勃度给你准备好了八个RequestTokenHandler.cs和AccessTokenHandler.cs,不过那多少个示范除了把您搞哭没啥大据守。

接下去,大家还亟需在此个文件中成功以下三件事:

新建二个request_token.ashx文件,像RequestTokenHandler.cs相仿持续
OAuth.Net.ServiceProvider.RequestTokenHandler这几个类,实现里面包车型地铁IssueRequestToken方
法,这时候,提出你就绝不再参谋示例项目里面包车型客车这些代码了,而去
OAuth.Net.瑟维斯Provider.RequestTokenHandler那个类里面,仿效它的IssueRequestToken
方法。因为示例项目里面包车型大巴token和secret都以写死的(包涵consumer也是写死的),因而它从不对转移的token做其余保存的动作。实际
上,你必要将以此token保存到数据Curry,同有的时候间保留callbackurl,至于要调用CallbackStore来保存大概你直接操作本身的数目库字
段,不在乎。那么些文件最终是把变化的token和secret以纯文本的款型再次回到给顾客端。

验证 UHavalL 中的数据
验证 Session 中的 token 数据
验证 Session 中的 secret 数据

然后客商端把收获的token字符串作为参数,跳到你的authorize.aspx页面,这里您须要提供顾客的登陆框,和四个授权开关。当客户点
下授权按键的时候,检查客户名密码是还是不是科学,然后依据客商跳转过来的时候传过来的格外oauth_token参数,找到您前面生成的
request_token对应的此外字段(要是您要对request_token设置有效时间,这里需求看清该时间),读出里面包车型大巴callbackurl字段,然后,调用
ServiceProviderContext.VerificationProvider.Generate(卡塔尔国方法依据该request_token
生成三个oauth_verifier字符串,将该值附加到callbackurl的背后,跳转过去。不过在跳转过去事情发生在此以前,你必得做风姿洒脱件事。

假定持有数据库都以合法的,咱们必要成立二个新的 SinaOAuth
对象实例,跟以前差别的是,我们要把获得到的 token
数据做为参数字传送入对象。之后,大家相应能够博获得一个 access
token,那些获得到的数据应该是一个数组,那么些 access token
是大家唯豆蔻年华供给保存起来的数目。

顾客的callbackurl页面收到你的oauth_verifier以后,再会同后面包车型地铁request_token一同来访谈你的
access_token.ashx,申请access_t0ken。所以客商端也不得不保留你前目生成的request_token才得以(有时性的,每一次授权前读取,申请到access_token就作废,所以平常用session来保存就能够了)。对于access_token.ashx的原委,源码同样提供了一个事例,不过相近是个一点用都未曾的例子,因为它完全未有关系到授权和浮动全局唯风流洒脱access_token的进程。你能够令你的
access_token的handler世襲自OAuth.Net.ServiceProvider.AccessTokenHandler,然后重写
IssueAccessToken方法。那些方法其实相当粗略,因为父类已经帮您检查评定了传过来的具有的参数以致签字的不利,以至连
access_token和verifier是还是不是合营都印证过了,所以你要做的正是把相应的access_token再次回到给客户。你能够生成二个新的
access_token再次来到给客商,因为它当中含有的token和secret其实便是五个不足为奇的字符串,前面边用到的兼具的变量都没有直接涉及,你只
要封存token是当世无双的就足以了,因为今后客商做有所的央求,实际都只使用那一个token字符串作为自己的并世无双身份标识。所以,无可否认,你要把转变的
这些access_token长久性的保存到和睦的数据Curry,还要把那几个token跟进行授权的顾客的id关联起来,以便未来每一遍能够查询到那几个顾客的身
份,本事传递他的数据回去。

建立callback.php

等等,顾客端在申请access_token的时候,只传递了request_token和一个verifier的字符串过来,授权的顾客的音讯并未再传回到,你什么掌握把哪叁个客户关联到那么些access_token上?

getAccessToken($_REQUEST['oauth_verifier']);
  // 将获取到的 access token 保存到 Session 中
  $_SESSION['access_token'] = $access_token;
  // 获取用户信息
  $user_info = $sinaOAuth->get('account/verify_credentials');
  // 打印用户信息
  mysql_connect(DATABASE_HOST, DATABASE_USER, DATABASE_PSSWORD);
  mysql_select_db(DATABASE_DB_NAME);
  //更换成你的数据库连接,在config.php中
  if (isset($user_info->error) or empty($user_info['id']))
  {
    // Something's wrong, go back to square 1
    header('Location: index.php');
  } else
  {
    // Let's find the user by its ID
    $sql = "SELECT * FROM oauth_users WHERE oauth_provider='sina' AND oauth_uid=" .$user_info['id'];
    $query = mysql_query($sql);
    $result = mysql_fetch_array($query);
    // If not, let's add it to the database
    if (empty($result))
    {
      $sql = "INSERT INTO oauth_users (oauth_provider, oauth_uid, username, oauth_token, oauth_secret) VALUES ('sina', '" .
        $user_info['id'] . "', '" . $user_info['screen_name'] . "', '" . $access_token['oauth_token'] .
        "', '" . $access_token['oauth_token_secret'] . "')";
      $query = mysql_query($sql);
      $query = mysql_query("SELECT * FROM oauth_users WHERE id = ".mysql_insert_id());
      $result = mysql_fetch_array($query);
    } else
    {
      // Update the tokens
      $query = mysql_query("UPDATE oauth_users SET oauth_token = '" . $access_token['oauth_token'] .
        "', oauth_secret = '" . $access_token['oauth_token_secret'] .
        "' WHERE oauth_provider = 'sina' AND oauth_uid = " . $user_info['id']);
    }
    $_SESSION['id']=$result['id'];
    $_SESSION['username']=$result['username'];
    $_SESSION['oauth_uid']=$result['oauth_uid'];
    $_SESSION['oauth_provider']=$result['oauth_provider'];
    $_SESSION['oauth_token']=$result['oauth_token'];
    $_SESSION['oauth_secret']=$result['oauth_secret'];
    header('Location: update.php');
  }
} else
{
  // 数据不完整,转到上一步
  header('Location: index.php');
}

?>

据此,你须求把创建新access_token的进程提前,放到authorize的时候,在跳转回callbackurl此前,直接在那间创办一个新的access_token,将它和你的request_token还或者有你的客商的新闻涉及起来,保存到数据Curry。然后在用户申请
access_token的时候,你只要依据传递过来的request_token去数据Curry找到前面生成的access_token,把七个值重回给客商端就OK了。

您能够通过 $user_info->id 来获取客户的 ID,通过
$user_info->screen_name
来获得顾客名,等等,别的的新闻也得以透过意气风发致的主意获取。

近来,认证进程已经成功了,客户能够选拔你的数据接口了。

亟需入眼建议的是,oauth_verifier
这么些传回到的参数不能够被选定,若是上边的代码已经不易输出了顾客新闻,你能够试着再一次刷新页面,应该会看出页面会抛出八个错误消息,因为
oauth_verifier 已经被大家用过三次了。要重复使用,须求到 index.php
页面重新发起一个认证央求。

演示中也为你希图了叁个echoHandler的测量检验代码,不过,正剧的是,那几个代码并不带有其余身份验证的进程,是个完全透顶的单独的handler,不知底开采协会提供这么一个示范代码的意思何在?

顾客注册

您可以协和新建叁个echoHandler.ashx(或许随意怎么着名字),你须求从前边的
OAuth.Net.ServiceProvider.AccessTokenHandler作为模板最初你的行事。将它的代码完整的复制到你的
handler文件里面来,慢慢矫正。首先,ParseParamters里,检查参数完整性,把VerifierParameter删掉,相像的把
this.CheckVerifier(context,
requestContextState of Qatar;也删掉,verifier参数只在申请access_token的时候才会现出。然后把
parameters.AllowOnly检查进度删掉,原因很简单。然后改正SetRequestToken函数,它的代码是经过token参数找到
request_token对象,把它改成通过token参数读取你的数据Curry的access_token对象(当然,同有时候把它事关的顾客的音讯也读出
来),然后,把IssueAccessToken函数的进度改成你的作业管理进度,譬如输出个客户详细消息啥的。至于输出成json依然xml,就看您的
个人欢娱和客户的渴求了。每种业务管理的handler的回来格式实际是无固定格式的,因为那毕竟是跟你协和的网站专业紧凑相关的。

收获了顾客消息后,今后我们要开首把客商消息注册到我们生死与共的数据库中,当然前提是顾客未有在本地数据库注册过。

其一时候,你的网址的业内的RESTful格式的api接口就计划好了,借使客商有开垦今日头条博客园客商端的涉世,肖似的代码拿过来稍稍改改就能够幸不辱命你
的网站的OAuth认证,然后就能够一本万利的调用你的别样的数据接口了。(可是和讯前日早已初叶放大OAuth2.0接口,而oauth-dot-net类
库这段日子尚未曾提供2.0有关的证实办法。假若你有意思味,可以本身达成一下2.0的置换参数的进程,然后,告诉本人一下。

地点代码中的数据库链接音讯要改成你和谐的。假使客商已经存在于大家的数据库中,大家需求立异客户的
tokens 字段,因为这注明 脸书(TWT传祺.US卡塔尔(قطر‎ 生成了新的 tokens,数据库中的 tokens
已经晚点了。假诺客户不设有,大家必要新加一条记下,并将相关的多寡保存在
Session中,最后重定向回 update.php 页面。

里头update.php代码如下:

急需留意的是,下边代码中的 SQL
未有通过验证,你在骨子里行使的时候只怕要由此改变。连接数据库前,我们须求先证实一下顾客是否曾经报到。有了顾客名,大家就足以来得一条本性的招待新闻了:

  通过 OAuth 进行身份验证--Yourtion



Hello =$_SESSION['username'] ?>

那正是OAuth认证和仓库储存的主要进程,希望对你有援助。
代码下载:SinaOauth

上述正是本文所述的全体内容了,希望我们能够中意。

请您花一点光阴将文章共享给你的心上人照旧留下商量。我们将会由衷多谢您的扶植!

发表评论

电子邮件地址不会被公开。 必填项已用*标注