MST
星途 面试题库

面试题:CouchDB中如何通过视图过滤实现基本的安全控制

假设我们有一个CouchDB数据库,里面存储了用户的信息,包括用户名、邮箱和一些敏感的个人数据。现在要求你通过视图过滤,使得普通用户只能看到自己的用户名和邮箱,看不到敏感个人数据,你将如何实现?请描述具体步骤及相关代码。
10.9万 热度难度
数据库CouchDB

知识考点

AI 面试

面试题答案

一键面试
  1. 创建视图

    • 在CouchDB中,视图是通过在数据库的 _design 文档中定义的。首先,我们需要创建一个设计文档,例如 security_view
    • 视图函数通常用JavaScript编写。以下是创建视图的大致步骤:
      • 使用CouchDB的API(例如通过HTTP请求)创建 _design/security_view 文档。
      • 在设计文档中定义 views 部分。
  2. 视图函数代码

    • 假设文档结构如下,每个用户文档类似:
    {
        "_id": "user1",
        "username": "john_doe",
        "email": "john@example.com",
        "sensitive_data": "confidential information"
    }
    
    • 我们的视图函数可以这样定义:
    function (doc) {
        if (doc.username && doc.email) {
            emit(doc._id, {
                username: doc.username,
                email: doc.email
            });
        }
    }
    
    • 在这个视图函数中,我们仅 emit 用户名和邮箱字段,忽略了敏感数据。
  3. 安全访问控制

    • 为了确保普通用户只能看到自己的数据,我们需要结合CouchDB的安全机制。
    • 一种常见的方法是在CouchDB的 _users 数据库中管理用户认证。
    • 假设用户在客户端通过认证后,我们可以在查询视图时添加限制。例如,在客户端查询视图时,添加条件使得只返回与当前认证用户用户名匹配的数据。如果使用HTTP请求查询视图,可以在查询参数中添加过滤条件:
    http://your_couchdb_server/your_database/_design/security_view/_view/your_view_name?key="john_doe"
    
    • 这里假设视图名称为 your_view_name,并且通过 key 参数指定只返回用户名匹配的数据。

    完整的创建设计文档(假设使用Python的 requests 库):

    import requests
    import json
    
    couchdb_url = "http://localhost:5984"
    db_name = "your_database"
    design_doc = {
        "_id": "_design/security_view",
        "views": {
            "filtered_user_view": {
                "map": "function (doc) { if (doc.username && doc.email) { emit(doc._id, { username: doc.username, email: doc.email }); } }"
            }
        }
    }
    
    response = requests.put(f"{couchdb_url}/{db_name}/_design/security_view", json=design_doc)
    if response.status_code == 201:
        print("Design document created successfully.")
    else:
        print(f"Error creating design document: {response.status_code} - {response.text}")
    

    然后在客户端根据认证用户的用户名查询视图,以确保只看到自己的数据。具体的客户端查询代码取决于使用的编程语言和CouchDB客户端库。例如,在JavaScript中使用 nano 库:

    const nano = require('nano')('http://localhost:5984');
    const db = nano.use('your_database');
    const username = "john_doe"; // 假设认证后的用户名
    db.view('security_view', 'filtered_user_view', { key: username }, function (err, body) {
        if (!err) {
            console.log(body.rows.map(row => row.value));
        } else {
            console.error(err);
        }
    });