BasicAuth认证是配合RESTful API 使用的最简单的认证方式,只需提供用户名密码即可。这里介绍python和java在项目中实现BasicAuth的方法。
Basic Auth认证的方式,是客户端在向服务器发请求的时候,会在请求头(header)中提供用户名和密码作为认证信息,它会通过BASE64编码将其进行编码处理,最后在请求头中存在格式为"Authorization":'basic '+b64Val
。其中b64Val为经过base64转码后的用户名密码信息,即b64Val=base64.b64encode('username:password')
在python中,我们可以使用flask完成BasicAuth认证。首先只需要引入 BasicAuth、配置 app.config、实例化BasicAuth,就可以使用BasicAuth了。
from flask import Flask
from flask_basicauth import BasicAuth
app = Flask(__name__)
basic_auth = BasicAuth(app)
//
app.config['BASIC_AUTH_USERNAME'] = 'admin'
app.config['BASIC_AUTH_PASSWORD'] = '123456'
//这里设置为true表示默认对所有的api进行认证;如果设置为False则需要手动添加@basic_auth_required对指定的api进行认证
app.config['BASIC_AUTH_FORCE'] = True
此时我们就可以对我们的api.route接口路径进行拦截认证了
@app.route('/test')
def test():
return 'Hello World!'
Flask-BasicAuth核心源码:
class BasicAuth(object):
def __init__(self, app=None):
if app is not None:
self.app = app
self.init_app(app)
else:
self.app = None
//判断是否该api需要进行认证
def init_app(self, app):
app.config.setdefault('BASIC_AUTH_FORCE', False)
app.config.setdefault('BASIC_AUTH_REALM', '')
@app.before_request
def require_basic_auth():
if not current_app.config['BASIC_AUTH_FORCE']:
return
if not self.authenticate():
return self.challenge()
//将输出的用户名和密码与默认设置的BASIC_AUTH_USERNAME和BASIC_AUTH_PASSWORD进行比较,判断是否一致
def check_credentials(self, username, password):
correct_username = current_app.config['BASIC_AUTH_USERNAME']
correct_password = current_app.config['BASIC_AUTH_PASSWORD']
return username == correct_username and password == correct_password
Java中实现BasicAuth认证,一般定义自定义拦截器的方式来实现。
首先需要我们定义一个拦截器:BasicAuthInterceptor
@Slf4j
@Component
public class BasicAuthInterceptor implements HandlerInterceptor {
//Controller处理之前调用-即是我们拦截的所在
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
String auth = httpServletRequest.getHeader("Authorization");
if (StrUtil.isNotBlank(auth)) {
//加密过程
String username = 项目中保存的用户名;
String password = 项目中保存的密码;
byte[] bytes = ( username + ":" + password).getBytes("utf-8");
//采用Base64编码
String encode = BasicAuthInfo.BASIC + new BASE64Encoder().encode(bytes).replace("\n", "");
//与传入的auth进行对比
if (encode.equals(auth)) {
return true;
}
log.error("auth 认证失败!!!");
//抛出异常处理
}else {
log.error("auth 认证信息不存在!!!");
//抛出异常处理
}
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
接着,我们定义一个BasicAuthConfig类,设置需要拦截认证的路径:
@Configuration
public class BasicAuthConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration registration = registry.addInterceptor(new BasicAuthInterceptor());
registration
//拦截所有请求
.addPathPatterns("/**")
//这里设置了Swagger放行,可以添加你所需要不进行拦截的路径
.excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**", "/doc.html/**");
}
}