本文主要介绍和xero oauth的集成过程,以后再与其他第三方的oauth的集成过程也将类似。 另外由于xero官方的文档非常有限,因此有必要进行总结一下。
xero 是一个财务系统,可用于替代产品账单模块的实现。
www.xero.com
了解oauth :
http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
http://baike.baidu.com/view/6619164.htm
概括起来就是,对于systema用户要访问systemb的资源,sysb的用户可以指定将sysb中的哪些部分(模块)暴露出来给sysa进行访问,同时会给sysa一个token和证书。每次sysa访问sysb时需要带上token以及证书。
1. 安装 nuget pkg :
2. 创建wapper 来封装交互过程
前提:
1.需要已经安装证书
2.已经得到了key/secret
public class xeroapiadapter
{
private readonly ixeroapiparameter _parameter;
private const string partner_url = "https://api-partner.network.xero.com";
private const string base_url = "https://api.xero.com";
public xerocoreapi coreapi { get; private set; }
private readonly x509certificate2 _signingcertificate;
private readonly x509certificate2 _partnercertificate;
/// <summary>
///
/// </summary>
/// <param name="parameter"></param>
public xeroapiadapter(ixeroapiparameter parameter)
{
_signingcertificate = xerooauthsettings.fetch.signingcertificate.selectedcertificate;
if (_signingcertificate == null)
{
throw new exception("signing certificate must be defined");
}
_partnercertificate = xerooauthsettings.fetch.partnercertificate.selectedcertificate;
if (_partnercertificate == null)
{
throw new exception("partner certificate must be defined");
}
_parameter = parameter;
var user = new apiuser { organisationid = parameter.networkid, name = parameter.networkid };
coreapi = new xerocoreapi(partner_url,
new rupartnerauthethicator(partner_url, base_url, xerotokenservices.do,
_signingcertificate, _partnercertificate),
new consumer(parameter.consumerkey, parameter.consumersecret), user,
new defaultmapper(), new defaultmapper());
}
public partnermvcauthenticator mvcauthenticator(string callback)
{
return new partnermvcauthenticator(partner_url, base_url, callback, xerotokenservices.do,
_signingcertificate, _partnercertificate,
new consumer(_parameter.consumerkey, _parameter.consumersecret),
xerorequesttokenservices.do);
}
}
rupartnerauthethicator.cs (主要用于over write xero de authorizeuser函数,默认会打开浏览器):
public class rupartnerauthethicator : partnerauthenticator
{
public rupartnerauthethicator(string baseuri, string authorizeuri, itokenstore store, string signingcertificatepath, string certificatepath, string password) : base(baseuri, authorizeuri, "", store, signingcertificatepath, certificatepath, password)
{
}
public rupartnerauthethicator(string baseuri, string authorizeuri, itokenstore store, x509certificate2 signingcertificate, x509certificate2 certificate) : base(baseuri, authorizeuri, "", store, signingcertificate, certificate)
{
}
protected override string authorizeuser(itoken token)
{
throw new xerorenewaccesstokenexception("please renew access token");
}
}
3. 实现itoken 接口,分为request token和 access token。 即请求token和访问token,访问token需要做持久化,请求token可存内存中。
public class xerotokenservices : mongoservice, itokenstore
{
public static xerotokenservices do
{
get
{
return new xerotokenservices();
}
}
private xerotokenservices()
{
}
private mongocollection<mdxerotoken> xerotokenstore
{
get
{
return connection.getmongocollection<mdxerotoken>("xerotokenstore");
}
}
public void add(itoken token)
{
//lets delete first as we are not sure if xero have a delete
delete(token);
xerotokenstore.save(new mdxerotoken(token));
}
public void delete(itoken token)
{
xerotokenstore.remove(query<mdxerotoken>.eq(x => x.userid, token.userid));
}
public itoken find(string user)
{
var token = xerotokenstore.findone(query<mdxerotoken>.eq(x => x.userid, user));
return token;
}
public void cleartokenfornetwork(string id)
{
xerotokenstore.remove(query<mdxerotoken>.eq(x => x.userid, id));
}
}
public class xerorequesttokenservices : mongoservice, itokenstore
{
public static xerorequesttokenservices do
{
get { return new xerorequesttokenservices(); }
}
private xerorequesttokenservices()
{
}
private mongocollection<mdxerotoken> xerotokenstore
{
get
{
return connection.getmongocollection<mdxerotoken>("xerorequesttokenstore");
}
}
public void add(itoken token)
{
//lets delete first as we are not sure if xero have a delete
delete(token);
xerotokenstore.save(new mdxerotoken(token));
}
public void delete(itoken token)
{
xerotokenstore.remove(query<mdxerotoken>.eq(x => x.userid, token.userid));
}
public itoken find(string user)
{
return xerotokenstore.findone(query<mdxerotoken>.eq(x => x.userid, user));
}
public void cleartokenfornetwork(string id)
{
xerotokenstore.remove(query<mdxerotoken>.eq(x => x.userid, id));
}
}
4. 指定callback 函数, 在xero配置callback domain
4.1 添加application
4.2 配置call back domain , 生成key , secret
4.3 call back 函数:
public actionresult authorize(string oauth_token, string oauth_verifier, string org, string redirect)
{
var network = networksmanagment.do.getnetwork(tenant.networkid);
var xeroapi = new xeroapiadapter(new xeroapiparam(network));
var authenthicator = xeroapi.mvcauthenticator("");
try
{
// - call xerotokenservices.add and store the token in mdxerotoken
var token = authenthicator.retrieveandstoreaccesstoken(network.id, oauth_token, oauth_verifier, org);
var organization = xeroapi.coreapi.organisation;
...
tempdata.addnotification(notifcationtype.success, "xero connected successfully");
}
catch (exception ex)
{
tempdata.addnotification("error connecting to xero", ex);
}
if (string.isnullorempty(redirect))
{
return redirecttoaction("index");
}
return redirect(redirect);
}
xero 官方 git:
https://github.com/xeroapi/xero-net
以上就是使用c# 与xero oauth 交互 集成 的内容。