zoukankan      html  css  js  c++  java
  • c# 自定义验证登录(Authorize)

    我们的项目本来是用azure的auth认证,是用过程中发现登录速度太慢了,所以还是自己搞一个吧,没想到搞起来挺简单的,不是用一个专门的认证服务器哈,就是一个简单的工具类。

    验证是否登录的类

        /// <summary>
        /// 认证类继承
        /// </summary>
        public class RequestAuthorizeAttribute : AuthorizeAttribute
        {
            public override void OnAuthorization(HttpActionContext actionContext)
            {
                // 是否不需要验证 或者 已经登录
                if (SkipAuthorization(actionContext) || IsLogin(actionContext))
                    return;
    
                actionContext.Response = GetResponse();
            }
    
            /// <summary>
            /// 返回信息接口
            /// </summary>
            private HttpResponseMessage GetResponse()
            {
                var response = ServiceResponse<bool>.WarningResponse(401, CommonConst.Msg_NoLogin, false);
                return JsonHelper.ToHttpResponseMessage(response);
            }
    
            /// <summary>
            /// 判断是否匿名使用接口
            /// </summary>
            private static bool SkipAuthorization(HttpActionContext actionContext)
            {
                if (!actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any<AllowAnonymousAttribute>())
                    return actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any<AllowAnonymousAttribute>();
                return true;
            }
    
            /// <summary>
            /// 是否已经登录
            /// </summary>
            private bool IsLogin(HttpActionContext actionContext)
            {
                var authorization = Guid.Empty.ToString(); // MD5值
                if (actionContext.Request.Headers.Authorization != null)
                {
                    authorization = actionContext.Request.Headers.Authorization.ToString();
                }
    
                var user = OperatorProvider.Provider.GetCurrent(authorization);
                return user != null;
            }
        }

    获取header值:

    参考资料:获取header

    代码如下:

            private bool IsLogin(HttpActionContext actionContext)
            {
                var token = Guid.Empty.ToString(); // MD5值
                var openId = string.Empty; // MD5值
    
                actionContext.Request.Headers.TryGetValues("Token", out var tokens);
                actionContext.Request.Headers.TryGetValues("OpenId", out var openIds);
                if (tokens.IsNotNull() && tokens.Any() && openIds.IsNotNull() && openIds.Any())
                {
                    token = tokens.FirstOrDefault();
                    openId = openIds.FirstOrDefault();
    
                    var cache = CacheHelper.GetCache(token);
                    if (cache.IsNotNull())//如果缓存中存在该token对应的值,说明已经登录了
                        return true;
    
                    //获取用户
                    var strUserUrl = HttpUtility.UrlDecode(ConfigurationManager.AppSettings["sso_req_user_url"]);
    
                    var reqUserUrl = string.Format(strUserUrl, openId, token);
                    var reqUser = WebRequest.Create(reqUserUrl) as HttpWebRequest;
                    reqUser.Method = "get";
                    reqUser.ContentType = "application/json";
                    var resUser = reqUser.GetResponse() as HttpWebResponse;
                    //以流的形式读取,返回的就是字符串的json格式
                    StreamReader readerUser = new StreamReader(resUser.GetResponseStream());
                    var resUserData = readerUser.ReadToEnd();
                    if (resUser.StatusCode == HttpStatusCode.OK)
                    {
                        var suser = JsonConvert.DeserializeObject<SSOUser>(resUserData);
                        var userId = Guid.Parse(suser.OpenId);
                        CacheHelper.SetCache(token, userId);
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                return false;
            }

    使用

    登录接口数据缓存处理,获取到用户信息后,生成guid作为token,每次登录都会重新生成token,返回给请求来源,web端只保存token值即可,每次请求的时候把token放到header里面。

    BaseApiController处理,获取header里面的token值,把用户信息放到缓存里面,从缓存中获取后放到基类里面的model中,子类都可以使用用户信息。

        [RequestAuthorize]
        public class BaseApiController : ApiController
        {
    
            /// <summary>
            /// 当前用户信息实体
            /// </summary>
            public OperatorModel CurrentUserModel
            {
                get
                {
                    var values = HttpContext.Current.Request.Headers.GetValues("authorization");
                    var authorization=Guid.Empty.ToString();
                    if (values != null && values.Length > 0)
                        authorization = values[0];
                    var currentUserModel = OperatorProvider.Provider.GetCurrent(authorization);
                    if (currentUserModel == null)
                    {
                        currentUserModel = new OperatorModel { LoginName = "admin" };
                    }
                    return currentUserModel;
                }
            }
        }

     web端使用token(VUE)

    token帮助类

    import Cookies from 'js-cookie'
    
    const TokenKey = 'hs_t'
    
    export function getToken() {
      return Cookies.get(TokenKey)
    }
    
    export function setToken(token) {
      return Cookies.set(TokenKey, token)
    }
    
    export function removeToken() {
      return Cookies.remove(TokenKey)
    }

    login.vue

    <template>
      <div class="login-container">
        <el-form ref="model" :model="model" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
          <div class="title-container">
            <h3 class="title">教师中心</h3>
          </div>
    
          <el-form-item prop="LoginName">
            <span class="svg-container">
              <svg-icon icon-class="user" />
            </span>
            <el-input ref="LoginName" v-model="model.LoginName" placeholder="登录名" name="LoginName" type="text" tabindex="1"
              autocomplete="on" />
          </el-form-item>
    
          <el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
            <el-form-item prop="password">
              <span class="svg-container">
                <svg-icon icon-class="password" />
              </span>
              <el-input :key="passwordType" ref="password" v-model="model.password" :type="passwordType" placeholder="密码"
                name="password" tabindex="2" autocomplete="on" @keyup.enter.native="login" />
              <span class="show-pwd" @click="showPwd">
                <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
              </span>
            </el-form-item>
          </el-tooltip>
    
          <el-button :loading="loading" type="primary" style="100%;margin-bottom:30px;" @click.native.prevent="login">
            登录</el-button>
        </el-form>
      </div>
    </template>
    <script>
      import { deepClone } from "@/utils";
      import { setToken, getToken } from '@/utils/auth'
      import { login } from "@/api/user";
    
      const defaulModel = {
        LoginName: "",
        password: "",
        orgCode: "",
        phone: "",
        UserType: "Teacher"
      };
    
      export default {
        name: 'Login',
        data() {
    
          return {
            model: deepClone(defaulModel),
            loginForm: {
              username: 'admin',
              password: '111111'
            },
            loginRules: {
              LoginName: [
                { required: true, message: "请输入登录名", trigger: 'blur' }
              ],
              password: [
                { required: true, message: "请输入密码", trigger: 'blur' }
              ]
            },
            passwordType: 'password',
            capsTooltip: false,
            loading: false,
            showDialog: false,
            redirect: undefined,
            otherQuery: {}
          }
        },
        created() {
          // window.addEventListener('storage', this.afterQRScan)
        },
        methods: {
          showPwd() {
            if (this.passwordType === 'password') {
              this.passwordType = ''
            } else {
              this.passwordType = 'password'
            }
            this.$nextTick(() => {
              this.$refs.password.focus()
            })
          },
          async login() {
            var v = true;
            this.$refs.model.validate(valid => {
              v = valid;
            });
            if (!v) {
              //验证不通过
              return false;
            }
            var res = await login(this.model)
            console.log(res)
            if (res.code == 200) {
              setToken(res.data)
              this.$router.push("/");
            }
          }
        }
      }
    </script>
  • 相关阅读:
    Ajax笔记(三)
    Ajax笔记(二)
    org.apache.commons.lang.StringUtils中常用的方法
    数位dp poj1850
    二分图 最小点覆盖 poj 3041
    poj 1789 prime
    c++三种进制格式
    c++面向行的输入getline()和get()
    最小生成树 prime算法 UVALive
    最短路 poj1125
  • 原文地址:https://www.cnblogs.com/dawenyang/p/11272534.html
Copyright © 2011-2022 走看看