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="width: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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM