问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

vue-resource 怎么解决跨域问题

发布网友 发布时间:2022-04-25 20:40

我来回答

3个回答

懂视网 时间:2022-04-10 06:09

1、为mobile用户申请access_token

     access_token存在并有效时,4+1种方式再次申请到的access_token都是一样的,有效期不变!

     如果mobile用户想使用【授权码模式】,需要修改数据库mobile_client支持的授权方式!

     如果使用mobile用户和授权码模式,要手工修改:申请用户mobile,申请客户mobile_client

2、使用得到的access_token直接访问服务提供者

      http://localhost:8080/spring-oauth-server/m/user_info?access_token=xxxxxxxxxxxxxxxxxx

技术分享

spring-oauth-server实践(1-5)为客户mobile-client开通授权码模式申请access_token,并使用access_token访问需要鉴权的业务

标签:oauth   token   images   bsp   user   http   用户   使用   server   

热心网友 时间:2022-04-10 03:17

上一篇我们介绍了如何使用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 CamelCasePropertyNamesContractResolver();

启用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 OAuthAuthorizationServerOptions 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 OAuthAuthorizationServerOptions

{

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(OAuthGrantResourceOwnerCredentialsContext context)

{

// ...

}

通俗地讲,客户端输入用户名、密码,点击登录后,会发起请求到www.example./token。

token这个请求在服务端执行的验证方法是什么呢?正是GrantResourceOwnerCredentials方法。

客户端发起验证请求时,必然是跨域的,token这个请求不属于任何ApiController的Action,而在WebApiConfig.cs中启用全局的CORS,只对ApiController有效,对token请求是不起作用的。

所以还需要在GrantResourceOwnerCredentials方法中添加一行代码:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext 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)

{

AllowOnlyAlphanumericUserNames = 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) {

热心网友 时间:2022-04-10 04:35

vue发送jsonp还有两个参数,我们来看看
Vue.http.jsonp(url,{params: {pageID:29},jsonp:"_callback"}) //这步就是关键,改callback名
这里params是要发送的数据对象,jsonp是设置回调的名称,也就是上面的callback名称;(不设置默认为callback),现在我们就需要
后台协助一下,获取我们发送过去的"_callpack"的值,将这个值拼接到返回的json数据上,这时候就可以了
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
四万元没开发票税务局发多少钱 不给开发票这个情节要罚多少钱? 广东乌龙茶的种类 银行什么时候拉征信 600795国电电力,为什么在2010年4,5月突然从8块跌到4块呢?涨幅-50%... 学习很差怎么逆袭 高考文科差生五十天冲刺计划!!! ...漂亮女人,那些不大漂亮的还很善良有点丑的怎么办?她们不是很可怜吗... CS1.6 AWP经典的FRAG视频 求链接 ...大家谁有AWP的视频或者DEMO,要个看看,学学,谢谢!~ 我家冰箱冷藏室老出水是怎么回事 在vue的页面里,需要用文字链接,请问需要配置什么 vuejs如何双向绑定传值之前处理值 海尔冰箱冷藏层总是往下化水,怎么办 PPR材料可燃吗? 冰箱上面冷藏室都化成水啦!原先冷藏室冰霜都化成水!怎么回事 哪位大侠知道塑胶原料PVC ABS PS PP PE PC PMMA的防火等级啊 感激不尽 冰箱冷藏的冰都化成水了怎么回事 前端页面用vue的一个博客框架,二者一起使用冲突吗 PP材料防火等级 pp材质的塑料高温有毒吗? 改性pp塑料材料有阻燃的作用吗? 常用的三种PP塑料阻燃剂有哪些 聚乙烯 聚丙烯 火灾危险性类别 防火pp塑料做出成品一年后出现霉点是什原因 阻燃防火PP塑料,注塑时为什么会出现粘模现象 我想买个10寸左右的平板电脑,不知什么牌子的好 常用的PP塑料阻燃剂有哪些? pp防火材料有哪些等级 10寸的平板电脑哪个牌子的好?求推荐 vue2.5.10以上的新版本,如何兼容ie11 vue中动态创建的元素怎样绑定事件博客园 webstorm怎么支持vue 苏州人均GDP排名全国第四,请问前三名是哪几个城市 杭州,苏州,谁更富裕??GDP高 苏州和杭州都是10强成员,苏州GDP高于杭州,那居民富裕程度呢? 支付宝电子身份证可以取火车票吗? 支付宝绑定了身份证,拍了正反面,可以用来取高铁票吗 人均GDP碾压广州,江苏这座城市为何不是一线城市? 支付宝里的电子身份证能在火车站售票窗口取票吗? 用支付宝买高铁票怎么取票?可以直接刷身份证吗?没坐过高铁,坐高铁和地铁是不是一样啊?请有坐过高铁的 苏州GDP接近两万亿直逼广州,怎么还不是一线城市? 支付宝买的高铁票没身份证能取票吗 苏州人均GDP和世界哪个国家相当 用支付宝买的高铁票去哪里取票 在支付宝上!预定高铁票后!怎样取?到火车站那个地方取! 第一次不懂 支付宝上的电子身份证能取火车票吗? 身份证忘带可以取高铁票不 莲子怎么吃法?莲子的芯需要去掉吗?莲子芯有何作用? 莲子怎么用最好?