第三方平台登录科工云
一.生成第三方配置
1.进入系统: 第三方平台-新增客户端。
2.会自动生成client_id,client_secret,填写第三方提供的回调地址(redirect_uri)。
3.点击立即提交进行保存。
二.科工云单点登录配置
科工云服务端配置
1.授权:http://auth.kegongyun.com/Oauth/Authorize
2.令牌:http://auth.kegongyun.com/Oauth/Token
3.用户:http://auth.kegongyun.com/Oauth/User
三.科工云作为服务端登录流程
3.1 第一步,开始授权验证,并且跳转到指定的授权页面。
/// <summary>
/// 第一步,开始授权验证
/// </summary>
/// <param name="client_id"></param>
/// <param name="response_type"></param>
/// <param name="redirect_uri"></param>
/// <param name="state"></param>
/// <param name="scope"></param>
/// <returns></returns>
public ActionResult Authorize(string client_id, string response_type, string redirect_uri, string scope, string state = "")
{
if ("code".Equals(response_type))
{
//判断client_id是否可用
if (!_oAuth2ServerServices.IsClientIdValied(client_id))
return this.Json("client_id 无效", JsonRequestBehavior.AllowGet);
//保存用户请求的所有信息到指定容器(session)
Session.Add("client_id", client_id);
Session.Add("response_type", response_type);
Session.Add("redirect_uri", redirect_uri);
Session.Add("state", state);
Session.Add("scope", scope);
//科工云未登录时需要先登录,去掉了授权页面,默认同意授权
if (member != null)
{
ViewBag.memberName = member.phone;
//return View();去掉授权页面
return RedirectToAction("Authenticate", "Oauth");
}
else
{
return RedirectToAction("index", "login");
}
}
return View("Error");
}
客户端默认授权后会请求授权验证方法
首先,验证client_id是否可用,这里的client_id是为了保证安全性,确保请求端是服务端给予请求或者授权的权利。简单地说,就是请求端在用此服务端之前要申请唯一的一个client_id;
然后,在把客户端传过来的信息保存在Session(你也可以保存在其他地方);
最后,跳转到同意授权后的操作
3.2 默认同意授权后返回code到请求端
生成code,并且设定code的生存时间,默认是30秒。(code只能用一次,之后要删除);
再绑定code与用户信息;
最后,重定向回redirect_uri请求的地址,并且返回code与state。(state是请求端那边想要用于处理一些业务逻辑所用到的,当然可以为空)
/// <summary>
/// 第二步,用户确认授权后的操作。
/// 用户确认授权后,则返回code、access_token,并重定向到redirect_uri所指定的页面
/// </summary>
/// <returns></returns>
public ActionResult Authenticate()
{
var member = LoginMember.Login();
//取得重定向的信息
var redirect_uri = Session["redirect_uri"] ?? "";
var state = Session["state"] ?? "";
string code = TokenCodeUtil.GetCode();
//保存code到DB/Redis,默认存在30秒
_oAuth2ServerServices.SaveCode(code);
//绑定code与member,因为后面查询用户信息的时候要用到,默认存在30秒
_oAuth2ServerServices.BingCodeAndUser(member, code);
//重定向
string url = string.Format(HttpUtility.UrlDecode(redirect_uri.ToString()) + "?code={0}&state={1}", code, state);
Response.Redirect(url);
return null;
}
3.3 获取token
在请求端获取到code之后,请求端要获取token,因为获取了token请求端才能获取到用户信息等资料。
首先,把token设置成不能保持cache的状态,为了保证安全性;
然后,判断是获取token还是刷新token的状态;
再验证code是否过期,验证client_id、client_secret是否正确;
再生成token,把token存入容器(DB、Redis、Memory等)中;
在通过code来获取用户的信息,把用户信息(主键)与token做绑定;
最后,把code删除(code只能用一次,如果想再获取token只能第一步开始重新做),返回token。
/// <summary>
/// 获取或刷新token。
/// token可能保存在DB/Redis等
/// </summary>
/// <param name="code"></param>
/// <param name="grant_type"></param>
/// <param name="client_id"></param>
/// <param name="client_secret"></param>
/// <returns></returns>
public ActionResult Token(string code, string grant_type, string client_id, string client_secret)
{
Response.ContentType = "application/json";
Response.AddHeader("Cache-Control", "no-store");
//获取token
if (grant_type == "authorization_code")
{
//判断code是否过期
if (!_oAuth2ServerServices.IsCodeValied(code, DateTime.Now))
return this.Json("code 过期", JsonRequestBehavior.AllowGet);
//判断client_id与client_secret是否正确
if (!_oAuth2ServerServices.IsClientValied(client_id, client_secret))
return this.Json("client_id、client_secret不正确", JsonRequestBehavior.AllowGet);
//新建token
string access_token = TokenCodeUtil.GetToken();
//保存token,默认是30分钟
_oAuth2ServerServices.SaveToken(access_token);
//通过code获取userid,然后用token与userid做绑定,最后把code设置成消失(删除)
string userId = _oAuth2ServerServices.GetUserIdFromCode(code);
if (string.IsNullOrEmpty(userId))
return this.Json("code过期", JsonRequestBehavior.AllowGet);
_oAuth2ServerServices.BingTokenAndUserId(access_token, userId);
_oAuth2ServerServices.RemoveCode(code);
//返回token
return this.Json(access_token, JsonRequestBehavior.AllowGet);
}
//刷新token
else if (grant_type == "refresh_token")
{
//新建token
string new_access_token = TokenCodeUtil.GetToken();
//替换保存新的token,默认是30分钟
//返回新建的token
return this.Json(new_access_token, JsonRequestBehavior.AllowGet);
}
return this.Json("error grant_type=" + grant_type, JsonRequestBehavior.AllowGet);
}
3.4 通过token获取用户信息
上面请求端已经获取到了token,所以这里只需要验证token,token验证通过就直接返回用户信息。
验证token包括验证是否存在、验证是否过期。
/// <summary>
/// 通过token获取用户信息
/// </summary>
/// <param name="oauth_token"></param>
/// <returns></returns>
public ActionResult User(string oauth_token)
{
if(!_oAuth2ServerServices.IsTokenValied(oauth_token, DateTime.Now))
return this.Json("oauth_token无效", JsonRequestBehavior.AllowGet);
UserInfo u = _oAuth2ServerServices.GetUserInfoFromToken(oauth_token);
return this.Json(u, JsonRequestBehavior.AllowGet);
}
文档更新时间: 2021-03-01 16:47 作者:admin