當前位置:首頁 » 網頁前端 » webapicors
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

webapicors

發布時間: 2023-01-24 09:43:11

① enablecors-webapi跨域 為何不能實現有哪些注意事項

上一篇我們介紹了如何使用vue resource處理請求,結合服務端的REST API,就能夠很容易地構建一個增刪查改應用。 這個應用始終遺留了一個問題,Web App在訪問REST API時,沒有經過任何認證,這使得服務端的REST API是不安全的,只要有人知道api地址,就可以調用API對服務端的資源進行修改和刪除。 今天我們就來探討一下如何結合Web API來限制資源的訪問。 本文的主要內容如下: 介紹傳統的Web應用和基於REST服務的Web應用 介紹OAuth認證流程和密碼模式 創建一個基於ASP. Identity的Web API應用程序 基於$.ajax實現OAuth的注冊、登錄、注銷和API調用 基於vue-resource實現OAuth的注冊、登錄、注銷和API調用 本文的最終示例是結合上一篇的CURD,本文的登錄、注冊、注銷和API調用功能實現的。 35 本文9個示例的源碼已放到GitHub,如果您覺得本篇內容不錯,請點個贊,或在GitHub上加個星星! Page Demo GitHub Source 基於$.ajax的示例如下: 注冊示例 登錄和注銷示例 登錄獲取token並調用API示例 注冊、登錄、注銷、調用API綜合示例 基於vue-resource的示例如下: 注冊示例 登錄和注銷示例 登錄獲取token並調用API示例 注冊、登錄...

② 如何讓WEBAPI 能夠進行跨越訪問

Cors是個比較熱的技術,這在蔣金楠的博客里也有體現,Cors簡單來說就是「跨域資源訪問」的意思,這種訪問我們指的是Ajax實現的非同步訪問,形象點說就是,一個A網站公開一些介面方法,對於B網站和C網站可以通過發Xmlhttprequest請求來調用A網站的方法,對於xmlhttprequest封裝比較好的插件如jquery的$.ajax,它可以讓開發者很容易的編寫AJAX非同步請求,無論是Get,Post,Put,Delete請求都可以發送。
Cors並不是什麼新的技術,它只是對HTTP請求頭進行了一個加工,還有我們的Cors架構里,對jsonp也有封裝,讓開發者在使用jsonp訪問里,編寫的代碼量更少,更直觀,呵呵。(Jsonp和Json沒什麼關系,它是從一個URI返回一個Script響應塊,所以,JSONP本身是和域名沒關系的,而傳統上的JSON是走xmlhttprequest的,它在默認情況下,是不能跨域訪問的)

③ WebApi內置跨域功能,為什麼我就實現不了

在Web.config的system.webServer配置節下增加配置

<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" />
</customHeaders>
</httpProtocol>
如果通過jquery 跨域訪問,在伺服器端和客戶端需要分別配合:

1. 在伺服器端,需要為每一個請求進行授權。例如在消息頭中要有
Access-Control-Allow-Origin:*
2. 在客戶端要寫
jQuery.support.cors = true;

④ vue-resource 怎麼解決跨域問題

上一篇我們介紹了如何使用vue resource處理請求,結合服務端的REST API,就能夠很容易地構建一個增刪查改應用。

這個應用始終遺留了一個問題,Web App在訪問REST API時,沒有經過任何認證,這使得服務端的REST API是不安全的,只要有人知道api地址,就可以調用API對服務端的資源進行修改和刪除。

今天我們就來探討一下如何結合Web API來限制資源的訪問。

本文的主要內容如下:

介紹傳統的Web應用和基於REST服務的Web應用

介紹OAuth認證流程和密碼模式

創建一個基於ASP. Identity的Web API應用程序

基於$.ajax實現OAuth的注冊、登錄、注銷和API調用

基於vue-resource實現OAuth的注冊、登錄、注銷和API調用

本文的最終示例是結合上一篇的CURD,本文的登錄、注冊、注銷和API調用功能實現的。

35

本文9個示例的源碼已放到GitHub,如果您覺得本篇內容不錯,請點個贊,或在GitHub上加個星星!

Page Demo GitHub Source

基於$.ajax的示例如下:

注冊示例 登錄和注銷示例 登錄獲取token並調用API示例 注冊、登錄、注銷、調用API綜合示例

基於vue-resource的示例如下:

注冊示例 登錄和注銷示例 登錄獲取token並調用API示例 注冊、登錄、注銷、調用API綜合示例

OAuth介紹

傳統的Web應用

在傳統的Web應用程序中,前後端是放在一個站點下的,我們可以通過會話(Session)來保存用戶的信息。

例如:一個簡單的ASP. MVC應用程序,用戶登錄成功後,我們將用戶的ID記錄在Session中,假設為Session["UserID"]。

前端發送ajax請求時,如果這個請求要求已登錄的用戶才能訪問,我們只需在後台Controller中驗證Session["UserID"]是否為空,就可以判斷用戶是否已經登錄了。

這也是傳統的Web應用能夠逃避面向無連接的方法。

基於REST服務的Web應用

當今很多應用,客戶端和服務端是分離的,服務端是基於REST風格構建的一套Service,客戶端是第三方的Web應用,客戶端通過跨域的ajax請求獲取REST服務的資源。

然而REST Service通常是被設計為無狀態的(Stateless),這意味著我們不能依賴於Session來保存用戶信息,也不能使用Session["UserID"]這種方式確定用戶身份。

解決這個問題的方法是什麼呢?常規的方法是使用OAuth 2.0。

對於用戶相關的OpenAPI,為了保護用戶數據的安全和隱私,第三方Web應用訪問用戶數據前都需要顯式的向用戶徵求授權。

相比於OAuth 1.0,OAuth 2.0的認證流程更加簡單。

專用名詞介紹

在了解OAuth 2.0之前,我們先了解幾個名詞:

Resource:資源,和REST中的資源概念一致,有些資源是訪問受保護的

Resource Server:存放資源的伺服器

Resource Owner:資源所有者,本文中又稱為用戶(user)

User Agent:用戶代理,即瀏覽器

Client: 訪問資源的客戶端,也就是應用程序

Authorization Server:認證伺服器,用於給Client提供訪問令牌的伺服器

Access Token:訪問資源的令牌,由Authorization Server器授予,Client訪問Resource時,需提供Access Token

Bearer Token:Bearer Token是Access Token的一種,另一種是Mac Token。

Bearer Token的使用格式為:Bearer XXXXXXXX

Token的類型請參考:s://tools.ietf/html/draft-ietf-oauth-v2-15#section-7.1

有時候認證伺服器和資源伺服器可以是一台伺服器,本文中的Web API示例正是這種運用場景。

OAuth認證流程

在知道這幾個詞以後,我們用這幾個名詞來編個故事。

簡化版本

這個故事的簡化版本是:用戶(Resource Owner)訪問資源(Resource)。

image

具體版本

簡化版的故事只有一個結果,下面是這個故事的具體版本:

用戶通過瀏覽器打開客戶端後,客戶端要求用戶給予授權。

客戶端可以直接將授權請求發給用戶(如圖所示),或者發送給一個中間媒介,比如認證伺服器。

用戶同意給予客戶端授權,客戶端收到用戶的授權。

授權模式(Grant Type)取決於客戶端使用的模式,以及認證伺服器所支持的模式。

客戶端提供身份信息,然後向認證伺服器發送請求,申請訪問令牌

認證伺服器驗證客戶端提供的身份信息,如果驗證通過,則向客戶端發放令牌

客戶端使用訪問令牌,向資源伺服器請求受保護的資源

資源伺服器驗證訪問令牌,如果有效,則向客戶端開放資源

image

以上幾個步驟,(B)是較為關鍵的一個,即用戶怎麼樣才能給客戶端授權。有了這個授權以後,客戶端就可以獲取令牌,進而通過臨牌獲取資源。這也是OAuth 2.0的運行流程,詳情請參考:s://tools.ietf/html/draft-ietf-oauth-v2-15#section-1.2

客戶端的授權模式

客戶端必須得到用戶的授權(authorization grant),才能獲得令牌(access token)。

OAuth 2.0定義了四種授權方式:

授權碼模式(authorization code)

簡化模式(implicit)

密碼模式(resource owner password credentials)

客戶端模式(client credentials)

本文的示例是基於密碼模式的,我就只簡單介紹這種模式,其他3我就不介紹了,大家有興趣可以看阮大的文章:

://http://www.yingtaow.com/sitemap.html?blog/2014/05/oauth_2_0.html

密碼模式

密碼模式(Resource Owner Password Credentials Grant)中,用戶向客戶端提供自己的用戶名和密碼。客戶端使用這些信息,向服務端申請授權。

在這種模式中,用戶必須把自己的密碼給客戶端,但是客戶端不得儲存密碼。這通常用在用戶對客戶端高度信任的情況下,比如客戶端是操作系統的一部分,或者由一個著名公司出品。

image

密碼嘛事的執行步驟如下:

(A)用戶向客戶端提供用戶名和密碼。

(B)客戶端將用戶名和密碼發給認證伺服器,向後者請求令牌。

(C)認證伺服器確認無誤後,向客戶端提供訪問令牌。

(B)步驟中,客戶端發出的請求,包含以下參數:

grant_type:表示授權類型,此處的值固定為"password",必選項。

username:表示用戶名,必選項。

password:表示用戶的密碼,必選項。

scope:表示許可權范圍,可選項。

注意:在後面的客戶端示例中,除了提供username和password,grant_type也是必須指定為"password",否則無法獲取服務端的授權。

服務端環境准備

如果您是前端開發人員,並且未接觸過ASP. Web API,可以跳過此段落。

image

Authentication選擇Indivial User Accounts

image

創建這個Web API工程時,VS會自動引入Owin和Asp.Identity相關的庫。

image

修改ValuesController,除了IEnumerable<string> Get()操作外,其他操作都刪除,並為該操作應用[Authorize]特性,這表示客戶端必須通過身份驗證後才能調用該操作。

public class ValuesController : ApiController

{

// GET: api/Values

[Authorize]

public IEnumerable<string> Get()

{

return new string[] { "value1", "value2" };

}

}

添加Model, Controller

image

image

image

初始化資料庫

image

執行以下3個命令

image

image

執行以下SQL語句:

顯示代碼

CustomersController類有5個Action,除了2個GET請求外,其他3個請求分別是POST, PUT和DELETE。

為這3個請求添加[Authorize]特性,這3個請求必須通過身份驗證才能訪問。

隱藏代碼

public class CustomersController : ApiController

{

private ApplicationDbContext db = new ApplicationDbContext();

// GET: api/Customers

public IQueryable<Customer> GetCustomers()

{

return db.Customers;

}

// GET: api/Customers/5

[ResponseType(typeof(Customer))]

public async Task<IActionResult> GetCustomer(int id)

{

Customer customer = await db.Customers.FindAsync(id);

if (customer == null)

{

return NotFound();

}

return Ok(customer);

}

// PUT: api/Customers/5

[Authorize]

[ResponseType(typeof(void))]

public async Task<IActionResult> PutCustomer(int id, Customer customer)

{

// ...

}

// POST: api/Customers

[Authorize]

[ResponseType(typeof(Customer))]

public async Task<IActionResult> PostCustomer(Customer customer)

{

// ...

}

// DELETE: api/Customers/5

[ResponseType(typeof(Customer))]

[Authorize]

public async Task<IActionResult> DeleteCustomer(int id)

{

// ...

}

}

讓Web API以CamelCase輸出JSON

在Global.asax文件中添加以下幾行代碼:

var formatters = GlobalConfiguration.Configuration.Formatters;

var jsonFormatter = formatters.JsonFormatter;

var settings = jsonFormatter.SerializerSettings;

settings.Formatting = Formatting.Indented;

settings.ContractResolver = new ();

啟用CORS

在Nuget Package Manager Console輸入以下命令:

Install-Package Microsoft.Asp.WebApi.Cors

在WebApiConfig中啟用CORS:

public static class WebApiConfig

{

public static void Register(Configuration config)

{

var cors = new EnableCorsAttribute("*", "*", "*");

config.EnableCors(cors);

// ...

}

}

類說明

在執行上述步驟時,VS已經幫我們生成好了一些類

image

IdentityModels.cs:包含ApplicationDbContext類和ApplicationUser類,無需再創建DbContext類

public class ApplicationUser : IdentityUser

{

// ...

}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>

{

// ...

}

Startup.Auth.cs:用於配置OAuth的一些屬性。

public partial class Startup

{

public static OAuthOptions { get; private set; }

public static string PublicClientId { get; private set; }

// For more information on configuring authentication, please visit ://go.microsoft./fwlink/?LinkId=301864

public void ConfigureAuth(IAppBuilder app)

{

// ..

// Configure the application for OAuth based flow

PublicClientId = "self";

OAuthOptions = new

{

TokenEndpointPath = new PathString("/Token"),

Provider = new ApplicationOAuthProvider(PublicClientId),

AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),

AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),

// In proction mode set AllowInsecure = false

AllowInsecure = true

};

// Enable the application to use bearer tokens to authenticate users

app.UseOAuthBearerTokens(OAuthOptions);

// ..

}

}

這些OAuth配置項,我們只用關注其中的兩項:

TokenEndpointPath:表示客戶端發送驗證請求的地址,例如:Web API的站點為www.example.,驗證請求的地址則為www.example./token。

UseOAuthBearerTokens:使用Bearer類型的token_type(令牌類型)。

ApplicationOAuthProvider.cs:默認的OAuthProvider實現,GrantResourceOwnerCredentials方法用於驗證用戶身份信息,並返回access_token(訪問令牌)。

public override async Task GrantResourceOwnerCredentials( context)

{

// ...

}

通俗地講,客戶端輸入用戶名、密碼,點擊登錄後,會發起請求到www.example./token。

token這個請求在服務端執行的驗證方法是什麼呢?正是GrantResourceOwnerCredentials方法。

客戶端發起驗證請求時,必然是跨域的,token這個請求不屬於任何ApiController的Action,而在WebApiConfig.cs中啟用全局的CORS,只對ApiController有效,對token請求是不起作用的。

所以還需要在GrantResourceOwnerCredentials方法中添加一行代碼:

public override async Task GrantResourceOwnerCredentials( context)

{

context.Response.Headers.Add("Access-Control-Allow-Origin", new []{"*"});

// ...

}

IdentityConfig.cs:配置用戶名和密碼的復雜度,主要用於用戶注冊時。例如:不允許用戶名為純字母和數字的組合,密碼長度至少為6位…。

隱藏代碼

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)

{

var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));

// Configure validation logic for usernames

manager.UserValidator = new UserValidator<ApplicationUser>(manager)

{

= false,

RequireUniqueEmail = true

};

// Configure validation logic for passwords

manager.PasswordValidator = new PasswordValidator

{

RequiredLength = 6,

RequireNonLetterOrDigit = true,

RequireDigit = true,

RequireLowercase = true,

RequireUppercase = true,

};

// ...

return manager;

}

使用Postman測試GET和POST請求

測試GET請求

image

GET請求測試成功,可以獲取到JSON數據。

測試POST請求

image

POST請求測試不通過,提示:驗證不通過,請求被拒絕。

基於$.ajax實現注冊、登錄、注銷和API調用

服務端的環境已經准備好了,現在我們就逐個實現用戶注冊、登錄,以及API調用功能吧。

注冊

頁面的HTML代碼如下:

<div id="app">

<div class="container">

<span id="message">{{ msg }}</span>

</div>

<div class="container">

<div class="form-group">

<label>電子郵箱</label>

<input type="text" v-model="registerModel.email" />

</div>

<div class="form-group">

<label>密碼</label>

<input type="text" v-model="registerModel.password" />

</div>

<div class="form-group">

<label>確認密碼</label>

<input type="text" v-model="registerModel.confirmPassword" />

</div>

<div class="form-group">

<label></label>

<button @click="register">注冊</button>

</div>

</div>

</div>

創建Vue實例,然後基於$.ajax發送用戶注冊請求:

var demo = new Vue({

el: '#app',

data: {

registerUrl: '://localhost:10648/api/Account/Register',

registerModel: {

email: '',

password: '',

confirmPassword: ''

},

msg: ''

},

methods: {

register: function() {

var vm = this

vm.msg = ''

$.ajax({

url: vm.registerUrl,

type: 'POST',

dataType: 'json',

data: vm.registerModel,

success: function() {

vm.msg = '注冊成功!'

},

error: vm.requestError

})

},

requestError: function(xhr, errorType, error) {

⑤ 前端學習到什麼程度可以找工作

對學習前端的同學來說,你能力越高就越好找工作。因為現在的前端求職市場不缺初級前端,初級前端已經飽和了。一大批剛學完三大項的人就急沖沖除去找工作了,這就導致找不到工作的同時、公司也找不到人。那到底要學到什麼樣子呢?
入門: 能用html css實現任何網站的靜態布局。 這個難度不大,能做到就能達到切圖仔的水平
可以幹活: 能用js寫基本動態效果, 綁定事件, 用原生或jq操作dom。
勉強合格: 以上兩項達到熟練, 並可以用js寫較復雜的交互。 到這里就可以找到前端的工作並幹活了。
合格: 知道如何實現js的繼承,能說出一個new的過程, 會合理用閉包, 會用promise, amd cmd模塊化, 會用underscore,能寫正則。 會其中兩到三項。 到這里應該可以找到缺人並還算不錯的互聯網公司前端工作
還行: 能手寫js的原型鏈繼承, 知道一個promise的實現機制, 能寫出underscore中大部分函數, 手寫delegate, 隨便找個庫基本能看明白是幹嘛。 到這里應該可以沖bat了吧。
不錯: 對頁面性能的優化有研究, mvc框架能夠分析出個優缺點所以然來, 對打包發布工具有研究。 到這份上能算靠譜的前端了吧
牛人: 根據業務需要寫所需的打包發布模塊化工具, 有能力自己寫框架, 對開發流程和方式有自己的見解, 不依賴類庫, 項目需要啥就隨手寫一個模塊, 造過輪子無數。 到這份上國內前端工作可以任挑了。

⑥ js調用跨域get請求調用webApi 多出個options請求是為什麼

我嘗試用我的語言描述一下吧:

先說跨域請求的原理,瀏覽器的安全機制是不允許出現跨域請求的,否則會有很嚴重的安全問題,解決跨域問題有幾種不同的方法,你題目中提到的方法就是通過在Response header中添加Access-Control-Allow-Origin 來讓瀏覽器知道伺服器所在的域,對用於訪問的域進行了授權。

但是因為這個Header要伺服器提供,所以無論如何,請求是要先發出去才能指導是不是允許跨域請求,所以在報跨域錯誤的時候,雖然報錯了,但是請求實際上依然發送到伺服器了,只是瀏覽器看了一眼伺服器的返回,然後發覺不行,這個請求返回的header里沒有授權,所以瀏覽器不能用。

這樣就帶來一個問題,請求會對伺服器造成影響,試想一下,要使用XHR跨域提交一個表單,無論返回頭裡面是否添加了跨域的header,都會提交一個請求到伺服器,伺服器要進行相應的操作。這種情況其實在一定條件下也是可以接受的,但是如果有更大的安全隱患,就不可以了,所以就需要OPTIONS請求了。

OPTIONS請求就是在符合一定條件下的跨域請求發送之前,瀏覽器會先發一個OPTIONS請求,問一下伺服器,是不是能跨域,如果能,就發真正的請求,如果不能,就不發了。這個的作用就很好理解了。

如上面所說,不是所有的跨域請求都要先發OPTIONS請求的,規范裡面規定,以下情況不需要先發一個 OPTIONS請求:

  1. 請求類型必須是GET、HEAD、POST中的一種。

  2. 請求的Header裡面只能包涵一些規范重點Header,以及規范的值,包括:Accept、Accept-Language、Content-Language、Content-Type、DPR、Downlink、Save、Data、Viewport-Width、Width

  3. Content-Type的類型必須是以下幾種:application/x-www-form-urlencoded、multipart/form-data、text/plain

所以,如果你不希望瀏覽器多餘的發一個OPTIONS請求,只要遵循這個規范就可以了。

但是有時候因為需求原因,也難避免要自定義一些Header。比如,很多JS的AJAX庫,都會自定義一個Header,讓伺服器可以識別出這是否是一個非同步請求,這樣OPTIONS請求就一定要被先發送了。

順便說,伺服器端也要判斷OPTIONS類型的請求,進行一系列操作,不要讓OPTIONS請求影響到數據。

更多內容,可以看相關資料和文檔:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

https://developer.mozilla.org/en-US/docs/Web/HTTP/Server-Side_Access_Control

https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html