首页 学海无涯 .NET Core ASP.NET Core第三方认证之QQ登录
ASP.NET Core第三方认证之QQ登录
摘要 之前写过一篇ASP.NET MVC使用QQ登录的案例,该篇主要将的是ASP.NET Core中使用QQ第三方认证登录。由于Nuget上已经有人上传了第三方认证的包,所以我们开发起来相对较简单。

1.在Web项目中引用Nuget包:Microsoft.AspNetCore.Authentication.QQ




2.添加配置信息

        在appsettings.json添加如下配置:

{
  "Authentication": {
    "QQ": {
      "AppId": "你的AppId",
      "AppKey": "你的AppKey"
    }
  }
}


3.配置Startup.cs

        注册认证服务:在ConfigureServices方法添加以下代码

//注册认证服务
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        //这里填写一些配置信息,默认即可
    })    //添加Cookie认证
    .AddQQ(qqOptions =>
    {
        qqOptions.AppId = Configuration["Authentication:QQ:AppId"];    //QQ互联申请的AppId
        qqOptions.AppKey = Configuration["Authentication:QQ:AppKey"];    //QQ互联申请的AppKey
        qqOptions.CallbackPath = "/user/callback";    //QQ互联回调地址
        //自定义认证声明
        qqOptions.ClaimActions.MapJsonKey(MyClaimTypes.QQOpenId, "openid");
        qqOptions.ClaimActions.MapJsonKey(MyClaimTypes.QQName, "nickname");
        qqOptions.ClaimActions.MapJsonKey(MyClaimTypes.QQFigure, "figureurl_qq_1");
        qqOptions.ClaimActions.MapJsonKey(MyClaimTypes.QQGender, "gender");
    });

        使用认证中间件:在Configure方法添加以下代码

//使用验证中间件
app.UseAuthentication();


4.登录处理

        在UserController中需要写两个Action,一个用来触发QQ登录,一个用来处理登录成功后的逻辑。例如:

public IActionResult Login(string provider = "QQ", string returnUrl = null)
{
    //第三方登录成功后跳转的地址
    var redirectUrl = Url.Action(nameof(ExternalLoginCallbackAsync), new { returnUrl });
    var properties = new AuthenticationProperties()
    {
        RedirectUri = redirectUrl
    };
    return Challenge(properties, provider);
}

[Authorize]
public async Task ExternalLoginCallbackAsync(string returnUrl = null)
{
    //QQ认证后会默认登录,如果你想自定义登录,可以先注销第三方登录的身份
    //await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

    string openId = "", name = "", figure = "", gender = "";
    //从当前登录用户的身份声明中获取信息(是否有些眼熟,MyClaimTypes就是在Startup里面自定义的那些)
    foreach (var item in HttpContext.User.Claims)
    {
        switch (item.Type)
        {
            case MyClaimTypes.QQOpenId:
                openId = item.Value;
                break;
            case MyClaimTypes.QQName:
                name = item.Value;
                break;
            case MyClaimTypes.QQFigure:
                figure = item.Value;
                break;
            case MyClaimTypes.QQGender:
                gender = item.Value;
                break;
            default:
                break;
        }
    }
    //获取到OpenId后进行登录或者注册(以下作为示范,不要盲目复制粘贴)
    if (!openId.IsNullOrEmpty())
    {
        //去数据库查询该QQ是否绑定用户
        User user = await _dbContext.User.Where(s => s.QQOpenId == openId).FirstOrDefaultAsync();
        if (user != null)
        {
            #region 存在则登陆
            var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
            identity.AddClaim(new Claim(ClaimTypes.Sid, user.Id.ToString()));
            identity.AddClaim(new Claim(ClaimTypes.Name, user.Name));
            identity.AddClaim(new Claim(MyClaimTypes.Avator, user.Avatar));
            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), new AuthenticationProperties
            {
                IsPersistent = true,
                ExpiresUtc = DateTimeOffset.Now.Add(TimeSpan.FromDays(int.Parse(Configuration["AppSettings:LoginExpires"]))) // 有效时间
            });
            user.LastLoginIP = HttpContext.GetUserIP();
            user.LastLoginTime = DateTime.Now;
            //更新登录信息
            _dbContext.User.Update(user);
            await _dbContext.SaveChangesAsync();
            #endregion

            if (returnUrl != null)
                return Redirect(returnUrl);
            else
                return RedirectToAction("index", "home");
        }
        else
        {
            User userModel = new User();
            userModel.QQOpenId = openId;
            userModel.Name = name;
            userModel.Avatar = figure;
            userModel.Gender = gender;
            userModel.CreateTime = DateTime.Now;
            //注册
            await _dbContext.User.AddAsync(userModel);
            if (await _dbContext.SaveChangesAsync() > 0)
            {

                #region 注册后自动登陆
                var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
                identity.AddClaim(new Claim(ClaimTypes.Sid, userModel.Id.ToString()));
                identity.AddClaim(new Claim(ClaimTypes.Name, userModel.Name));
                identity.AddClaim(new Claim(MyClaimTypes.Avator, userModel.Avatar));
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), new AuthenticationProperties
                {
                    IsPersistent = true,
                    ExpiresUtc = DateTimeOffset.Now.Add(TimeSpan.FromDays(int.Parse(Configuration["AppSettings:LoginExpires"]))) // 有效时间
                });
                userModel.LastLoginIP = HttpContext.GetUserIP();
                userModel.LastLoginTime = DateTime.Now;
                //更新登录信息
                _dbContext.User.Update(userModel);
                await _dbContext.SaveChangesAsync();
                #endregion

                if (returnUrl != null)
                    return Redirect(returnUrl);
                else
                    return RedirectToAction("index", "home");
            }
            else
                throw new Exception("Add User failed");
        }
    }
    else
        throw new Exception("OpenId is null");
}


4.开始使用

        在页面上放置触发QQ登录的按钮,如:

<a href="/user/login?provider=QQ&returnUrl=@returnUrl" >
    <i class="fa fa-qq"></i>
</a>

        provider=QQ是必须的,returnUrl一般写当前页面,这样登录成功后就可以跳转回当前页面。


5.结语

        该案例使用的是微软的认证组件,上文提到的provider需要注意,QQ登录必须写QQ。

        微软自身提供了Microsoft账号Google账号等国外账号的认证组件,用法应该和上述类似,有兴趣的去Github下载asp.net源码看看呗。

        此外Microsoft.AspNetCore.Authentication.QQ这个包在Github上也有源码,大家可以看看别人是怎么实现的,也能够知晓provider必须写QQ的原因,顺便自己封装个微博、微信登录也是可以的。


版权声明:本文由不落阁原创出品,转载请注明出处!

本文链接:http://www.leo96.com/article/detail/29

本文配乐
来说两句吧

该文章已禁止评论

最新评论
  • 滥好人
    滥好人

    感谢大佬,又学到了,涨知识了[微笑]

    ASP.NET Core准备有时间了学习一下


    刘杰⭐️
    刘杰⭐️ 回复 滥好人 我也有这想法

    2018-05-24 13:28回复

    hongsir撤回了一条消息
    hongsir撤回了一条消息 回复 刘杰⭐️ +1

    2018-07-17 16:02回复

    hongsir撤回了一条消息
    hongsir撤回了一条消息 回复 滥好人 +1

    2018-07-17 16:02回复

  • 庞
    666
  • 技术再高也怕菜🔪
    技术再高也怕菜🔪
    为什么一定要跳转到当前页面呢
  • 技术再高也怕菜🔪
    技术再高也怕菜🔪
    我想请教下webapi是如何操作的呢?